From 3ace905edd29bda7ecfc0166301a8f8651938440 Mon Sep 17 00:00:00 2001 From: Remy Willems Date: Fri, 21 Feb 2025 00:14:14 +0100 Subject: [PATCH] Add serialization framework (#6112) Changes to enable reading serialized Dafny sources ### What was changed? - Create a script command `generate-deserializer` which generates a `Deserializer` class that takes a `IDecoder` and returns an instance of the Dafny AST, which is in a post-parsing state. - Enable the `dafny` CLI to consume `.dbin` files that contains serialized Dafny code, and create an option `--input-format` that allows the `--stdin` command to accept serialized input. - Create a script command `generate-parsed-ast` which create a version of the Dafny AST that only contains fields which filled in through source code. This is useful for other languages to generate their version of the Dafny post-parsing AST. - Create a script command `source-to-binary` that takes a Dafny program and outputs its serialized format, based on the C# types generated by `generate-parsed-ast`. This command is used for testing both of the above code generation commands. To enable testing the above commands using a minimal "assert false" Dafny program, the following changes were made as well: - Add nullable annotations to the Dafny AST in some places, together with `#nullable enable` annotations in this files, and fixes for the nullability warnings in those files. - Add `ParseConstructorAttribute` to some constructors in the Dafny AST - Remove some fields from the Dafny AST that always held the same value. - Rename certain fields/properties and constructor parameters, so the names match ### Future work - Currently the 'interface definition language' is C# types. We can still switch to any of the existing IDL languages in a separate PR. I think most of the code would remain the same. However, I'm not convinced it makes sense to use another IDL so I won't further investigate that,. - The serialization format is schemaless, and the code is setup so that the format can be easily changed by providing a different implementation of `IDecoder`. Currently there's only a text based format, but it would be easy to add a byte based one. The text based format could be improved with newlines and indentation so it's easier to read. ### Caveats - Given an abstract type like `Expression`, the generator only visits subtypes that have a constructor annotated with `[ParseConstructor]`, which is intentionally missing for many types right now. Because it is missing for those types, not the entire Dafny AST is generated, which means we can work more incrementally. - The generators require that each parameter of a constructor can be mapped to a field or property, and fail otherwise. This PR does not update CI so that the generators are run, so the AST could become out of date after this PR is merged. ### How has this been tested? - Added `inputFormat.dfy` CLI test, which takes a Dafny file, serializes it to a file, deserializes it from that file, and then verifies it. - TODO Add CI checks to ensure the generated code is up-to-date By submitting this pull request, I confirm that my contribution is made under the terms of the [MIT license](https://github.com/dafny-lang/dafny/blob/master/LICENSE.txt). --- .github/workflows/msbuild.yml | 2 +- .github/workflows/runtime-tests.yml | 3 + .pre-commit-config.yaml | 2 +- Makefile | 16 +- Source/DafnyCore.Test/ClonerTest.cs | 3 +- Source/DafnyCore/AST/Attributes.cs | 91 +++-- Source/DafnyCore/AST/Cloner.cs | 20 +- .../AST/Expressions/AttributedExpression.cs | 5 +- .../DafnyCore/AST/Expressions/LiteralExpr.cs | 6 + .../AST/Expressions/Specification.cs | 17 +- .../AST/Expressions/Variables/Formal.cs | 1 + .../DafnyCore/AST/Grammar/Printer/Printer.cs | 6 +- Source/DafnyCore/AST/Grammar/ProgramParser.cs | 26 +- Source/DafnyCore/AST/Members/Field.cs | 2 +- Source/DafnyCore/AST/Members/Function.cs | 8 +- Source/DafnyCore/AST/Members/MemberDecl.cs | 6 +- Source/DafnyCore/AST/Members/Method.cs | 16 +- .../DafnyCore/AST/Members/MethodOrFunction.cs | 22 +- .../AST/Modules/AbstractModuleDecl.cs | 2 +- .../DafnyCore/AST/Modules/AliasModuleDecl.cs | 2 +- .../DafnyCore/AST/Modules/DefaultClassDecl.cs | 12 +- .../AST/Modules/FileModuleDefinition.cs | 6 +- .../AST/Modules/LiteralModuleDecl.cs | 2 +- Source/DafnyCore/AST/Modules/ModuleDecl.cs | 4 +- .../DafnyCore/AST/Modules/ModuleDefinition.cs | 11 +- .../DafnyCore/AST/Modules/ModuleExportDecl.cs | 5 +- Source/DafnyCore/AST/SourceOrigin.cs | 1 + Source/DafnyCore/AST/Statements/BlockStmt.cs | 5 + .../AST/Statements/ControlFlow/Label.cs | 4 +- Source/DafnyCore/AST/Statements/Statement.cs | 15 +- .../Statements/Verification/AssertLabel.cs | 6 +- .../AST/Statements/Verification/AssertStmt.cs | 14 +- .../AST/Statements/Verification/AssumeStmt.cs | 4 +- .../AST/Statements/Verification/ExpectStmt.cs | 4 +- .../Statements/Verification/PredicateStmt.cs | 5 +- .../AST/SyntaxDeserializer/Generated.cs | 317 ++++++++++++++++++ .../AST/SyntaxDeserializer/HandWritten.cs | 181 ++++++++++ .../AST/SyntaxDeserializer/IDecoder.cs | 12 + .../AST/SyntaxDeserializer/TextDecoder.cs | 117 +++++++ Source/DafnyCore/AST/SystemModuleManager.cs | 8 +- Source/DafnyCore/AST/Tokens.cs | 7 +- .../AST/TypeDeclarations/AbstractTypeDecl.cs | 8 +- .../AST/TypeDeclarations/ClassDecl.cs | 2 +- .../AST/TypeDeclarations/ClassLikeDecl.cs | 6 +- .../AST/TypeDeclarations/DatatypeCtor.cs | 2 +- .../AST/TypeDeclarations/DatatypeDecl.cs | 5 +- .../AST/TypeDeclarations/Declaration.cs | 18 +- .../AST/TypeDeclarations/NewtypeDecl.cs | 8 +- .../AST/TypeDeclarations/NonNullTypeDecl.cs | 2 +- .../AST/TypeDeclarations/SubsetTypeDecl.cs | 2 +- .../AST/TypeDeclarations/TopLevelDecl.cs | 9 +- .../TopLevelDeclWithMembers.cs | 23 +- .../AST/TypeDeclarations/TypeSynonymDecl.cs | 4 +- .../TypeDeclarations/TypeSynonymDeclBase.cs | 6 +- .../AST/TypeDeclarations/ValuetypeDecl.cs | 4 +- Source/DafnyCore/AST/Types/TypeParameter.cs | 53 +-- .../AST/Types/TypeParameterCharacteristics.cs | 39 +++ Source/DafnyCore/AST/Types/Types.cs | 4 +- .../Backends/CSharp/CsharpCodeGenerator.cs | 2 +- .../Backends/Dafny/DafnyCodeGenerator.cs | 4 +- .../Backends/DatatypeWrapperEraser.cs | 2 +- .../Backends/GoLang/GoCodeGenerator.cs | 8 +- .../Backends/Java/JavaCodeGenerator.cs | 2 +- .../JavaScript/JavaScriptCodeGenerator.cs | 4 +- .../Backends/Python/PythonCodeGenerator.cs | 4 +- Source/DafnyCore/Dafny.atg | 8 +- Source/DafnyCore/Generic/Name.cs | 2 +- Source/DafnyCore/Generic/Node.cs | 20 ++ Source/DafnyCore/Generic/RangeNode.cs | 1 + Source/DafnyCore/Options/CommonOptionBag.cs | 10 + Source/DafnyCore/Options/DafnyCommands.cs | 3 +- .../DafnyCore/Resolver/AmbiguousMemberDecl.cs | 2 +- .../Resolver/AmbiguousTopLevelDecl.cs | 2 +- .../CheckTypeCharacteristicsVisitor.cs | 2 +- Source/DafnyCore/Resolver/ModuleResolver.cs | 8 +- .../Resolver/PreType/PreTypeConstraints.cs | 2 +- .../Resolver/PreType/PreTypeResolve.cs | 2 +- .../Resolver/TypeCharacteristicChecker.cs | 2 +- .../Rewriters/RefinementTransformer.cs | 2 +- .../Verifier/BoogieGenerator.Methods.cs | 2 +- Source/DafnyCore/Verifier/BoogieGenerator.cs | 4 +- .../DafnyDriver/Commands/BoogieExtractor.cs | 2 +- Source/DafnyDriver/DafnyDoc.cs | 4 +- .../Language/Symbols/SymbolTableFactory.cs | 2 +- .../Workspace/ProjectManager.cs | 2 +- .../binaries/DafnyStandardLibraries-cs.doo | Bin 1552 -> 1548 bytes .../binaries/DafnyStandardLibraries-go.doo | Bin 1575 -> 1567 bytes .../binaries/DafnyStandardLibraries-java.doo | Bin 1545 -> 1544 bytes .../binaries/DafnyStandardLibraries-js.doo | Bin 2038 -> 2031 bytes .../DafnyStandardLibraries-notarget.doo | Bin 1529 -> 1525 bytes .../binaries/DafnyStandardLibraries-py.doo | Bin 1543 -> 1539 bytes .../binaries/DafnyStandardLibraries.doo | Bin 57096 -> 57385 bytes .../src/Std/JSON/ZeroCopy/Serializer.dfy | 2 + .../IntegrationTests/DafnyDriverLitCommand.cs | 1 + .../IntegrationTests/IntegrationTests.csproj | 1 + Source/IntegrationTests/LitTests.cs | 9 + .../LitTests/LitTest/cli/inputFormat.dfy | 7 + .../LitTest/cli/inputFormat.dfy.expect | 3 + Source/Scripts/IEncoder.cs | 9 + Source/Scripts/MainClass.cs | 15 + Source/Scripts/PostParseAstVisitor.cs | 206 ++++++++++++ Source/Scripts/Program.cs | 13 - Source/Scripts/ResourceLoader.cs | 32 ++ Source/Scripts/Scripts.csproj | 13 +- Source/Scripts/SourceToBinary.cs | 249 ++++++++++++++ Source/Scripts/Syntax.cs-schema | 216 ++++++++++++ Source/Scripts/SyntaxDeserializerGenerator.cs | 206 ++++++++++++ Source/Scripts/SyntaxSchemaGenerator.cs | 197 +++++++++++ Source/Scripts/TextEncoder.cs | 62 ++++ 109 files changed, 2244 insertions(+), 296 deletions(-) create mode 100644 Source/DafnyCore/AST/SyntaxDeserializer/Generated.cs create mode 100644 Source/DafnyCore/AST/SyntaxDeserializer/HandWritten.cs create mode 100644 Source/DafnyCore/AST/SyntaxDeserializer/IDecoder.cs create mode 100644 Source/DafnyCore/AST/SyntaxDeserializer/TextDecoder.cs create mode 100644 Source/DafnyCore/AST/Types/TypeParameterCharacteristics.cs create mode 100644 Source/IntegrationTests/TestFiles/LitTests/LitTest/cli/inputFormat.dfy create mode 100644 Source/IntegrationTests/TestFiles/LitTests/LitTest/cli/inputFormat.dfy.expect create mode 100644 Source/Scripts/IEncoder.cs create mode 100644 Source/Scripts/MainClass.cs create mode 100644 Source/Scripts/PostParseAstVisitor.cs delete mode 100644 Source/Scripts/Program.cs create mode 100644 Source/Scripts/ResourceLoader.cs create mode 100644 Source/Scripts/SourceToBinary.cs create mode 100644 Source/Scripts/Syntax.cs-schema create mode 100644 Source/Scripts/SyntaxDeserializerGenerator.cs create mode 100644 Source/Scripts/SyntaxSchemaGenerator.cs create mode 100644 Source/Scripts/TextEncoder.cs diff --git a/.github/workflows/msbuild.yml b/.github/workflows/msbuild.yml index 5e779c576a8..dfd1179af46 100644 --- a/.github/workflows/msbuild.yml +++ b/.github/workflows/msbuild.yml @@ -37,7 +37,7 @@ jobs: run: dotnet tool restore - name: Check whitespace and style working-directory: dafny - run: dotnet format whitespace Source/Dafny.sln --verify-no-changes --exclude Source/DafnyCore/Scanner.cs --exclude Source/DafnyCore/Parser.cs --exclude Source/DafnyCore/GeneratedFromDafny/* --exclude Source/DafnyCore.Test/GeneratedFromDafny/* --exclude Source/DafnyRuntime/DafnyRuntimeSystemModule.cs + run: dotnet format whitespace Source/Dafny.sln --verify-no-changes --exclude Source/DafnyCore/Generic/Deserializer/Generated.cs --exclude Source/DafnyCore/Scanner.cs --exclude Source/DafnyCore/Parser.cs --exclude Source/DafnyCore/GeneratedFromDafny/* --exclude Source/DafnyCore.Test/GeneratedFromDafny/* --exclude Source/DafnyRuntime/DafnyRuntimeSystemModule.cs - name: Check that it's possible to bump the version working-directory: dafny run: make bumpversion-test diff --git a/.github/workflows/runtime-tests.yml b/.github/workflows/runtime-tests.yml index 0d5888a133d..20c0adeccf8 100644 --- a/.github/workflows/runtime-tests.yml +++ b/.github/workflows/runtime-tests.yml @@ -49,6 +49,9 @@ jobs: run: dotnet build Source/Dafny.sln - name: Get Z3 run: make z3-ubuntu + - name: Test using outer Makefile + run: | + make test-integration - name: Test DafnyCore run: | cd ./Source/DafnyCore diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f4cdfba04b2..dfce53da623 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,5 +5,5 @@ repos: name: dotnet-format language: system entry: dotnet format whitespace Source/Dafny.sln -v:d --include - exclude: 'Source/DafnyCore/Scanner.cs|Source/DafnyCore/Parser.cs|.git/modules/Source/boogie|Source/DafnyCore/GeneratedFromDafny|Source/DafnyCore.Test/GeneratedFromDafny|Source/DafnyRuntime/DafnyRuntimeSystemModule.cs' + exclude: 'Source/DafnyCore/Generic/Deserializer/Generated.cs|Source/DafnyCore/Scanner.cs|Source/DafnyCore/Parser.cs|.git/modules/Source/boogie|Source/DafnyCore/GeneratedFromDafny|Source/DafnyCore.Test/GeneratedFromDafny|Source/DafnyRuntime/DafnyRuntimeSystemModule.cs' types_or: ["c#"] diff --git a/Makefile b/Makefile index 07d3eac3681..75c94f630f7 100644 --- a/Makefile +++ b/Makefile @@ -87,7 +87,7 @@ z3-ubuntu: chmod +x "${DIR}"/Binaries/z3/bin/z3-* format: - dotnet format whitespace Source/Dafny.sln --exclude Source/DafnyCore/Scanner.cs --exclude Source/DafnyCore/Parser.cs --exclude boogie --exclude Source/DafnyCore/GeneratedFromDafny/* --exclude Source/DafnyCore.Test/GeneratedFromDafny/* --exclude Source/DafnyRuntime/DafnyRuntimeSystemModule.cs + dotnet format whitespace Source/Dafny.sln --exclude Source/DafnyCore/Generic/Deserializer/Generated.cs --exclude Source/DafnyCore/Scanner.cs --exclude Source/DafnyCore/Parser.cs --exclude boogie --exclude Source/DafnyCore/GeneratedFromDafny/* --exclude Source/DafnyCore.Test/GeneratedFromDafny/* --exclude Source/DafnyRuntime/DafnyRuntimeSystemModule.cs clean: (cd "${DIR}"; cd Source; rm -rf Dafny/bin Dafny/obj DafnyDriver/bin DafnyDriver/obj DafnyRuntime/obj DafnyRuntime/bin DafnyServer/bin DafnyServer/obj DafnyPipeline/obj DafnyPipeline/bin DafnyCore/obj DafnyCore/bin) @@ -132,3 +132,17 @@ pr: exe dfy-to-cs-exe pr-nogeneration # Same as `make pr` but useful when resolving conflicts, to take the last compiled version of Dafny first pr-conflict: dfy-to-cs-exe dfy-to-cs-exe pr-nogeneration + +gen-integration: gen-schema gen-deserializer + +PARSED_AST_FILE=Source/Scripts/Syntax.cs-schema +gen-schema: + ./script.sh generate-parsed-ast $(PARSED_AST_FILE) + +GENERATED_DESERIALIZER_FILE=Source/DafnyCore/AST/SyntaxDeserializer/generated.cs +gen-deserializer: + ./script.sh generate-syntax-deserializer ${GENERATED_DESERIALIZER_FILE} + +test-integration: gen-integration + (git status --porcelain || (echo 'Consider running `make gen-integration`'; exit 1; )) + \ No newline at end of file diff --git a/Source/DafnyCore.Test/ClonerTest.cs b/Source/DafnyCore.Test/ClonerTest.cs index 2730f963463..24c708d1716 100644 --- a/Source/DafnyCore.Test/ClonerTest.cs +++ b/Source/DafnyCore.Test/ClonerTest.cs @@ -11,8 +11,7 @@ class DummyDecl : Declaration { public DummyDecl(Cloner cloner, Declaration original) : base(cloner, original) { } - public DummyDecl(IOrigin origin, Name name, Attributes attributes, bool isRefining) : base(origin, name, - attributes, isRefining) { + public DummyDecl(IOrigin origin, Name name, Attributes attributes) : base(origin, name, attributes) { } public override SymbolKind? Kind => null; diff --git a/Source/DafnyCore/AST/Attributes.cs b/Source/DafnyCore/AST/Attributes.cs index 451667b6e6e..7480f7697e1 100644 --- a/Source/DafnyCore/AST/Attributes.cs +++ b/Source/DafnyCore/AST/Attributes.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -20,7 +21,7 @@ public static bool IsExplicitAxiom(this IAttributeBearingDeclaration me) => public record BuiltInAtAttributeArgSyntax( string ArgName, Type ArgType, // If null, it means it's not resolved (@Induction and @Trigger) - Expression DefaultValue) { + Expression? DefaultValue) { public Formal ToFormal() { Contract.Assert(ArgType != null); return new Formal(Token.NoToken, ArgName, ArgType, true, false, @@ -34,7 +35,7 @@ public record BuiltInAtAttributeSyntax( string Name, List Args, Func CanBeApplied) { - public BuiltInAtAttributeSyntax WithArg(String argName, Type argType, Expression defaultValue = null) { + public BuiltInAtAttributeSyntax WithArg(String argName, Type argType, Expression? defaultValue = null) { var c = new List(Args) { new(argName, argType, defaultValue) }; return this with { Args = c }; @@ -63,9 +64,16 @@ void ObjectInvariant() { /*Frozen*/ public readonly List Args; - public readonly Attributes Prev; - public Attributes(string name, [Captured] List args, Attributes prev) : base(Token.NoToken) { - Contract.Requires(name != null); + public readonly Attributes? Prev; + + [SyntaxConstructor] + public Attributes(IOrigin origin, string name, List args, Attributes? prev) : base(origin) { + Name = name; + Args = args; + Prev = prev; + } + + public Attributes(string name, [Captured] List args, Attributes? prev) : base(Token.NoToken) { Contract.Requires(cce.NonNullElements(args)); Contract.Requires(name != UserSuppliedAtAttribute.AtName || this is UserSuppliedAtAttribute); Name = name; @@ -83,11 +91,11 @@ public override string ToString() { } } - public static IEnumerable SubExpressions(Attributes attrs) { + public static IEnumerable SubExpressions(Attributes? attrs) { return attrs.AsEnumerable().SelectMany(aa => aa.Args); } - public static bool Contains(Attributes attrs, string nm) { + public static bool Contains(Attributes? attrs, string nm) { Contract.Requires(nm != null); return attrs.AsEnumerable().Any(aa => aa.Name == nm); } @@ -97,7 +105,7 @@ public static bool Contains(Attributes attrs, string nm) { /// attribute. /// [Pure] - public static Attributes/*?*/ Find(Attributes attrs, string nm) { + public static Attributes? Find(Attributes? attrs, string nm) { Contract.Requires(nm != null); return attrs.AsEnumerable().FirstOrDefault(attr => attr.Name == nm); } @@ -111,7 +119,7 @@ public static bool Contains(Attributes attrs, string nm) { /// be called very early during resolution before types are available and names have been resolved. /// [Pure] - public static bool ContainsBool(Attributes attrs, string nm, ref bool value) { + public static bool ContainsBool(Attributes? attrs, string nm, ref bool value) { Contract.Requires(nm != null); var attr = attrs.AsEnumerable().FirstOrDefault(attr => attr.Name == nm); if (attr == null) { @@ -156,7 +164,7 @@ public static bool ContainsBoolAtAnyLevel(MemberDecl decl, string attribName, bo /// - if the attribute is {:nm e1,...,en}, then returns (e1,...,en) /// Otherwise, returns null. /// - public static List FindExpressions(Attributes attrs, string nm) { + public static List? FindExpressions(Attributes attrs, string nm) { Contract.Requires(nm != null); foreach (var attr in attrs.AsEnumerable()) { if (attr.Name == nm) { @@ -169,9 +177,8 @@ public static List FindExpressions(Attributes attrs, string nm) { /// /// Same as FindExpressions, but returns all matches /// - public static List> FindAllExpressions(Attributes attrs, string nm) { - Contract.Requires(nm != null); - List> ret = null; + public static List>? FindAllExpressions(Attributes? attrs, string nm) { + List>? ret = null; for (; attrs != null; attrs = attrs.Prev) { if (attrs.Name == nm) { ret = ret ?? []; // Avoid allocating the list in the common case where we don't find nm @@ -192,11 +199,9 @@ public static List> FindAllExpressions(Attributes attrs, string /// - return false, leave value unmodified, and call reporter with an error string. /// public enum MatchingValueOption { Empty, Bool, Int, String, Expression } - public static bool ContainsMatchingValue(Attributes attrs, string nm, ref object value, IEnumerable allowed, Action reporter) { - Contract.Requires(nm != null); - Contract.Requires(allowed != null); - Contract.Requires(reporter != null); - List args = FindExpressions(attrs, nm); + public static bool ContainsMatchingValue(Attributes attrs, string nm, ref object value, + ISet allowed, Action reporter) { + var args = FindExpressions(attrs, nm); if (args == null) { return false; } else if (args.Count == 0) { @@ -207,16 +212,15 @@ public static bool ContainsMatchingValue(Attributes attrs, string nm, ref object return false; } } else if (args.Count == 1) { - Expression arg = args[0]; - StringLiteralExpr stringLiteral = arg as StringLiteralExpr; - LiteralExpr literal = arg as LiteralExpr; - if (literal != null && literal.Value is bool && allowed.Contains(MatchingValueOption.Bool)) { + var arg = args[0]; + var literal = arg as LiteralExpr; + if (literal is { Value: bool } && allowed.Contains(MatchingValueOption.Bool)) { value = literal.Value; return true; } else if (literal != null && literal.Value is BigInteger && allowed.Contains(MatchingValueOption.Int)) { value = literal.Value; return true; - } else if (stringLiteral != null && stringLiteral.Value is string && allowed.Contains(MatchingValueOption.String)) { + } else if (arg is StringLiteralExpr stringLiteral && stringLiteral.Value is string && allowed.Contains(MatchingValueOption.String)) { value = stringLiteral.Value; return true; } else if (allowed.Contains(MatchingValueOption.Expression)) { @@ -300,8 +304,7 @@ private static Attributes A1(string name, ActualBindings bindings) { // Given a user-supplied @-attribute, expand it if recognized as builtin to an old-style attribute // or mark it as not built-in for later resolution - public static Attributes ExpandAtAttribute(Program program, UserSuppliedAtAttribute atAttribute, IAttributeBearingDeclaration attributeHost) { - var toMatch = atAttribute.Arg; + public static Attributes? ExpandAtAttribute(Program program, UserSuppliedAtAttribute atAttribute, IAttributeBearingDeclaration attributeHost) { var name = atAttribute.UserSuppliedName; var bindings = atAttribute.UserSuppliedPreResolveBindings; @@ -364,7 +367,7 @@ public static Attributes ExpandAtAttribute(Program program, UserSuppliedAtAttrib if (Get(bindings, 0, out var lowFuel) && lowFuel != null) { if (Get(bindings, 1, out var highFuel) && highFuel != null) { if (Get(bindings, 2, out var functionName) && IsStringNotEmpty(functionName)) { - return A("fuel", functionName, lowFuel, highFuel); + return A("fuel", functionName!, lowFuel, highFuel); } return A("fuel", lowFuel, highFuel); @@ -632,13 +635,13 @@ public static LiteralExpr DefaultInt(int value) { return Expression.CreateIntLiteralNonnegative(Token.NoToken, value); } - private static bool IsStringNotEmpty(Expression value) { + private static bool IsStringNotEmpty(Expression? value) { return value is StringLiteralExpr { Value: string and not "" }; } // Given resolved bindings, gets the i-th argument according to the // declaration formals order - private static bool Get(ActualBindings bindings, int i, out Expression expr) { + private static bool Get(ActualBindings bindings, int i, out Expression? expr) { if (bindings.Arguments.Count < i + 1) { expr = null; return false; @@ -667,7 +670,7 @@ private static void ResolveLikeDatatypeConstructor(Program program, Formal[] for } // Recovers a built-in @-Attribute if it exists - public static bool TryGetBuiltinAtAttribute(string name, out BuiltInAtAttributeSyntax builtinAtAttribute) { + public static bool TryGetBuiltinAtAttribute(string name, out BuiltInAtAttributeSyntax? builtinAtAttribute) { return BuiltInAtAttributeDictionary.TryGetValue(name, out builtinAtAttribute); } @@ -681,27 +684,27 @@ public static bool TryGetBuiltinAtAttribute(string name, out BuiltInAtAttributeS }, b => b); // Overridable method to clone the attribute as if the new attribute was placed after "prev" in the source code - public virtual Attributes CloneAfter(Attributes prev) { + public virtual Attributes CloneAfter(Attributes? prev) { return new Attributes(Name, Args, prev); } //////// Helpers for parsing attributes ////////////////// // Returns the memory location's attributes content and set the memory location to null (no attributes) - public static Attributes Consume(ref Attributes tmpStack) { + public static Attributes? Consume(ref Attributes? tmpStack) { var result = tmpStack; tmpStack = null; return result; } // Empties the first attribute memory location while prepending its attributes to the second attribute memory location, in the same order - public static void MergeInto(ref Attributes tmpStack, ref Attributes attributesStack) { + public static void MergeInto(ref Attributes? tmpStack, ref Attributes? attributesStack) { MergeIntoReadonly(tmpStack, ref attributesStack); tmpStack = null; } // Prepends the attributes tmpStack before the attributes contained in the memory location attributesStack - private static void MergeIntoReadonly(Attributes tmpStack, ref Attributes attributesStack) { + private static void MergeIntoReadonly(Attributes? tmpStack, ref Attributes? attributesStack) { if (tmpStack == null) { return; } @@ -718,7 +721,7 @@ public static class AttributesExtensions { /// /// By making this an extension method, it can also be invoked for a null receiver. /// - public static IEnumerable AsEnumerable(this Attributes attr) { + public static IEnumerable AsEnumerable(this Attributes? attr) { while (attr != null) { yield return attr; attr = attr.Prev; @@ -731,12 +734,8 @@ public class UserSuppliedAttributes : Attributes { public readonly IOrigin OpenBrace; public readonly IOrigin CloseBrace; public bool Recognized; // set to true to indicate an attribute that is processed by some part of Dafny; this allows it to be colored in the IDE - public UserSuppliedAttributes(IOrigin origin, IOrigin openBrace, IOrigin closeBrace, List args, Attributes prev) + public UserSuppliedAttributes(IOrigin origin, IOrigin openBrace, IOrigin closeBrace, List args, Attributes? prev) : base(origin.val, args, prev) { - Contract.Requires(origin != null); - Contract.Requires(openBrace != null); - Contract.Requires(closeBrace != null); - Contract.Requires(args != null); SetOrigin(origin); OpenBrace = openBrace; CloseBrace = closeBrace; @@ -749,22 +748,20 @@ public class UserSuppliedAtAttribute : Attributes { public readonly IOrigin AtSign; public bool Builtin; // set to true to indicate it was recognized as a builtin attribute // Otherwise it's a user-defined one and Arg needs to be fully resolved - public UserSuppliedAtAttribute(IOrigin origin, Expression arg, Attributes prev) + public UserSuppliedAtAttribute(IOrigin origin, Expression arg, Attributes? prev) : base(AtName, [arg], prev) { - Contract.Requires(origin != null); SetOrigin(origin); this.AtSign = origin; } public Expression Arg => Args[0]; - public override Attributes CloneAfter(Attributes prev) { + public override Attributes CloneAfter(Attributes? prev) { return new UserSuppliedAtAttribute(AtSign, Args[0], prev); } // Name of this @-Attribute, which is the part right after the @ - public string UserSuppliedName => - GetName(this); + public string? UserSuppliedName => GetName(this); // Pre-resolved bindings of this @-Attribute public ActualBindings UserSuppliedPreResolveBindings => @@ -776,7 +773,7 @@ public override Attributes CloneAfter(Attributes prev) { GetPreResolveArguments(this); // Gets the name of an @-attribute. Attributes might be applied. - public static string GetName(Attributes a) { + public static string? GetName(Attributes a) { if (a is UserSuppliedAtAttribute { Arg: ApplySuffix { Lhs: NameSegment { Name: var name } } }) { return name; } @@ -818,12 +815,12 @@ public static IEnumerable GetUserSuppliedArguments(Attributes a) { /// A class implementing this interface is one that can carry attributes. /// public interface IAttributeBearingDeclaration { - Attributes Attributes { get; internal set; } + Attributes? Attributes { get; internal set; } string WhatKind { get; } } public static class AttributeBearingDeclarationExtensions { - public static bool HasUserAttribute(this IAttributeBearingDeclaration decl, string name, out Attributes attribute) { + public static bool HasUserAttribute(this IAttributeBearingDeclaration decl, string name, out Attributes? attribute) { if (Attributes.Find(decl.Attributes, name) is UserSuppliedAttributes attr) { attribute = attr; return true; diff --git a/Source/DafnyCore/AST/Cloner.cs b/Source/DafnyCore/AST/Cloner.cs index 6a8c76b5634..304ab56dca4 100644 --- a/Source/DafnyCore/AST/Cloner.cs +++ b/Source/DafnyCore/AST/Cloner.cs @@ -68,7 +68,7 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne var dd = (AbstractTypeDecl)d; return new AbstractTypeDecl(Origin(dd.Origin), dd.NameNode.Clone(this), newParent, CloneTPChar(dd.Characteristics), dd.TypeArgs.ConvertAll(CloneTypeParam), - dd.ParentTraits.ConvertAll(CloneType), + dd.Traits.ConvertAll(CloneType), dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining); } else if (d is SubsetTypeDecl) { Contract.Assume( @@ -88,12 +88,12 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne if (dd.Var == null) { return new NewtypeDecl(Origin(dd.Origin), dd.NameNode.Clone(this), dd.TypeArgs.ConvertAll(CloneTypeParam), newParent, CloneType(dd.BaseType), dd.WitnessKind, CloneExpr(dd.Witness), - dd.ParentTraits.ConvertAll(CloneType), + dd.Traits.ConvertAll(CloneType), dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining); } else { return new NewtypeDecl(Origin(dd.Origin), dd.NameNode.Clone(this), dd.TypeArgs.ConvertAll(CloneTypeParam), newParent, CloneBoundVar(dd.Var, false), CloneExpr(dd.Constraint), dd.WitnessKind, CloneExpr(dd.Witness), - dd.ParentTraits.ConvertAll(CloneType), + dd.Traits.ConvertAll(CloneType), dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining); } } else if (d is TupleTypeDecl) { @@ -105,7 +105,7 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne var tps = dd.TypeArgs.ConvertAll(CloneTypeParam); var ctors = dd.Ctors.ConvertAll(CloneCtor); var dt = new IndDatatypeDecl(Origin(dd.Origin), dd.NameNode.Clone(this), newParent, tps, ctors, - dd.ParentTraits.ConvertAll(CloneType), + dd.Traits.ConvertAll(CloneType), dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining); return dt; } else if (d is CoDatatypeDecl) { @@ -113,7 +113,7 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne var tps = dd.TypeArgs.ConvertAll(CloneTypeParam); var ctors = dd.Ctors.ConvertAll(CloneCtor); var dt = new CoDatatypeDecl(Origin(dd.Origin), dd.NameNode.Clone(this), newParent, tps, ctors, - dd.ParentTraits.ConvertAll(CloneType), + dd.Traits.ConvertAll(CloneType), dd.Members.ConvertAll(d => CloneMember(d, false)), CloneAttributes(dd.Attributes), dd.IsRefining); return dt; } else if (d is IteratorDecl) { @@ -139,7 +139,7 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne var tps = dd.TypeArgs.ConvertAll(CloneTypeParam); var mm = dd.Members.ConvertAll(member => CloneMember(member, false)); var cl = new TraitDecl(Origin(dd.Origin), dd.NameNode.Clone(this), newParent, tps, mm, - CloneAttributes(dd.Attributes), dd.IsRefining, dd.ParentTraits.ConvertAll(CloneType)); + CloneAttributes(dd.Attributes), dd.IsRefining, dd.Traits.ConvertAll(CloneType)); return cl; } else if (d is DefaultClassDecl) { var dd = (DefaultClassDecl)d; @@ -151,7 +151,7 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne var tps = dd.TypeArgs.ConvertAll(CloneTypeParam); var mm = dd.Members.ConvertAll(member => CloneMember(member, false)); return new ClassDecl(Origin(dd.Origin), dd.NameNode.Clone(this), newParent, tps, mm, - CloneAttributes(dd.Attributes), dd.IsRefining, dd.ParentTraits.ConvertAll(CloneType)); + CloneAttributes(dd.Attributes), dd.IsRefining, dd.Traits.ConvertAll(CloneType)); } else if (d is ModuleDecl) { if (d is LiteralModuleDecl moduleDecl) { return new LiteralModuleDecl(this, moduleDecl, newParent); @@ -174,8 +174,8 @@ public virtual TopLevelDecl CloneDeclaration(TopLevelDecl d, ModuleDefinition ne } } - public TypeParameter.TypeParameterCharacteristics CloneTPChar( - TypeParameter.TypeParameterCharacteristics characteristics) { + public TypeParameterCharacteristics CloneTPChar( + TypeParameterCharacteristics characteristics) { TypeParameter.EqualitySupportValue eqSupport; if (characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.InferredRequired) { eqSupport = TypeParameter.EqualitySupportValue.Unspecified; @@ -183,7 +183,7 @@ public TypeParameter.TypeParameterCharacteristics CloneTPChar( eqSupport = characteristics.EqualitySupport; } - return new TypeParameter.TypeParameterCharacteristics(eqSupport, characteristics.AutoInit, + return new TypeParameterCharacteristics(eqSupport, characteristics.AutoInit, characteristics.ContainsNoReferenceTypes); } diff --git a/Source/DafnyCore/AST/Expressions/AttributedExpression.cs b/Source/DafnyCore/AST/Expressions/AttributedExpression.cs index 91a3ac621c2..ae009631e14 100644 --- a/Source/DafnyCore/AST/Expressions/AttributedExpression.cs +++ b/Source/DafnyCore/AST/Expressions/AttributedExpression.cs @@ -39,11 +39,12 @@ public AttributedExpression(Expression e) public AttributedExpression(Expression e, Attributes attrs) : this(e, null, attrs) { } - public AttributedExpression(Expression e, AssertLabel/*?*/ label, Attributes attrs) : base(e.Origin) { + [SyntaxConstructor] + public AttributedExpression(Expression e, AssertLabel/*?*/ label, Attributes attributes) : base(e.Origin) { Contract.Requires(e != null); E = e; Label = label; - Attributes = attrs; + Attributes = attributes; } public void AddCustomizedErrorMessage(IOrigin tok, string s) { diff --git a/Source/DafnyCore/AST/Expressions/LiteralExpr.cs b/Source/DafnyCore/AST/Expressions/LiteralExpr.cs index 897f3314e55..4d9051ce2de 100644 --- a/Source/DafnyCore/AST/Expressions/LiteralExpr.cs +++ b/Source/DafnyCore/AST/Expressions/LiteralExpr.cs @@ -48,6 +48,12 @@ public static bool IsEmptySequence(Expression e) { return StripParens(e) is SeqDisplayExpr display && display.Elements.Count == 0; } + [SyntaxConstructor] + public LiteralExpr(IOrigin origin, object value) + : base(origin) { + this.Value = value is int n ? new BigInteger(n) : value; + } + public LiteralExpr(IOrigin origin) : base(origin) { // represents the Dafny literal "null" Contract.Requires(origin != null); diff --git a/Source/DafnyCore/AST/Expressions/Specification.cs b/Source/DafnyCore/AST/Expressions/Specification.cs index cb45cd494ee..235be716e18 100644 --- a/Source/DafnyCore/AST/Expressions/Specification.cs +++ b/Source/DafnyCore/AST/Expressions/Specification.cs @@ -1,3 +1,4 @@ +#nullable enable using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -9,7 +10,6 @@ public class Specification : NodeWithComputedRange, IAttributeBearingDeclarat [ContractInvariantMethod] private void ObjectInvariant() { - Contract.Invariant(Expressions == null || cce.NonNullElements(Expressions)); } public Specification() { @@ -17,13 +17,18 @@ public Specification() { Attributes = null; } - public Specification(List exprs, Attributes attrs) { - Contract.Requires(exprs == null || cce.NonNullElements(exprs)); - Expressions = exprs; - Attributes = attrs; + [SyntaxConstructor] + public Specification(IOrigin origin, List expressions, Attributes attributes) : base(origin) { + Expressions = expressions; + Attributes = attributes; } - public Attributes Attributes { get; set; } + public Specification(List expressions, Attributes? attributes) { + Expressions = expressions; + Attributes = attributes; + } + + public Attributes? Attributes { get; set; } string IAttributeBearingDeclaration.WhatKind => "specification clause"; public bool HasAttributes() { diff --git a/Source/DafnyCore/AST/Expressions/Variables/Formal.cs b/Source/DafnyCore/AST/Expressions/Variables/Formal.cs index c123f797d9e..612ce882c22 100644 --- a/Source/DafnyCore/AST/Expressions/Variables/Formal.cs +++ b/Source/DafnyCore/AST/Expressions/Variables/Formal.cs @@ -22,6 +22,7 @@ public Formal(IOrigin origin, string name, Type type, bool inParam, bool isGhost isOld, isNameOnly, isOlder, nameForCompilation) { } + [SyntaxConstructor] public Formal(IOrigin origin, Name nameNode, Type type, bool inParam, bool isGhost, Expression defaultValue, Attributes attributes = null, bool isOld = false, bool isNameOnly = false, bool isOlder = false, string nameForCompilation = null) diff --git a/Source/DafnyCore/AST/Grammar/Printer/Printer.cs b/Source/DafnyCore/AST/Grammar/Printer/Printer.cs index 6e02e53546e..5f32bb5bcf7 100644 --- a/Source/DafnyCore/AST/Grammar/Printer/Printer.cs +++ b/Source/DafnyCore/AST/Grammar/Printer/Printer.cs @@ -711,7 +711,7 @@ public void PrintClass(ClassLikeDecl c, int indent, DafnyProject project) { private void PrintExtendsClause(TopLevelDeclWithMembers c) { string sep = " extends "; - foreach (var trait in c.ParentTraits) { + foreach (var trait in c.Traits) { wr.Write(sep); PrintType(trait); sep = ", "; @@ -1233,11 +1233,11 @@ public void PrintType(string prefix, Type ty) { } } - public string TPCharacteristicsSuffix(TypeParameter.TypeParameterCharacteristics characteristics) { + public string TPCharacteristicsSuffix(TypeParameterCharacteristics characteristics) { return TPCharacteristicsSuffix(characteristics, options.DafnyPrintResolvedFile != null); } - public static string TPCharacteristicsSuffix(TypeParameter.TypeParameterCharacteristics characteristics, bool printInferredTypeCharacteristics) { + public static string TPCharacteristicsSuffix(TypeParameterCharacteristics characteristics, bool printInferredTypeCharacteristics) { string s = null; if (characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.Required || (characteristics.EqualitySupport == TypeParameter.EqualitySupportValue.InferredRequired && printInferredTypeCharacteristics)) { diff --git a/Source/DafnyCore/AST/Grammar/ProgramParser.cs b/Source/DafnyCore/AST/Grammar/ProgramParser.cs index 9296c48580c..46b76609e9d 100644 --- a/Source/DafnyCore/AST/Grammar/ProgramParser.cs +++ b/Source/DafnyCore/AST/Grammar/ProgramParser.cs @@ -7,6 +7,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; +using Microsoft.Boogie; using Microsoft.Dafny.Compilers; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; @@ -17,6 +18,7 @@ namespace Microsoft.Dafny; public record DfyParseFileResult( int? Version, Uri Uri, + IReadOnlyList NewRootUris, BatchErrorReporter ErrorReporter, FileModuleDefinition Module, IReadOnlyList> ModifyBuiltins @@ -124,7 +126,7 @@ private DfyParseFileResult ParseFileWithErrorHandling(DafnyOptions options, var reporter = new BatchErrorReporter(options); reporter.Error(MessageSource.Parser, origin, $"Unable to open the file {uri} because {e.Message}."); - return new DfyParseFileResult(fileSnapshot.Version, uri, reporter, new FileModuleDefinition(Token.NoToken), + return new DfyParseFileResult(fileSnapshot.Version, uri, [], reporter, new FileModuleDefinition(Token.NoToken), new Action[] { }); } catch (OperationCanceledException) { throw; @@ -140,7 +142,7 @@ private DfyParseFileResult ParseFileWithErrorHandling(DafnyOptions options, var reporter = new BatchErrorReporter(options); reporter.Error(MessageSource.Parser, ErrorId.p_internal_exception, internalErrorDummyToken, "[internal error] Parser exception: " + e.Message + "\n" + e.StackTrace); - return new DfyParseFileResult(fileSnapshot.Version, uri, reporter, new FileModuleDefinition(Token.NoToken), + return new DfyParseFileResult(fileSnapshot.Version, uri, [], reporter, new FileModuleDefinition(Token.NoToken), new Action[] { }); } } @@ -163,6 +165,8 @@ private void ShowWarningsForIncludeCycles(Program program) { private static void AddParseResultToProgram(DfyParseFileResult parseFileResult, Program program, Dictionary versionedFiles) { + program.Compilation.RootSourceUris.AddRange(parseFileResult.NewRootUris); + if (parseFileResult.Version != null) { versionedFiles.Add(parseFileResult.Uri, parseFileResult.Version.Value); } @@ -276,8 +280,20 @@ protected virtual DfyParseFileResult ParseFile(DafnyOptions options, FileSnapsho Uri uri, CancellationToken cancellationToken) /* throws System.IO.IOException */ { Contract.Requires(uri != null); using var reader = fileSnapshot.Reader; - var text = SourcePreprocessor.ProcessDirectives(reader, []); - return ParseFile(options, fileSnapshot.Version, text, uri, cancellationToken); + + if (options.Get(CommonOptionBag.InputType) == CommonOptionBag.InputTypeEnum.Source) { + var text = SourcePreprocessor.ProcessDirectives(reader, []); + return ParseFile(options, fileSnapshot.Version, text, uri, cancellationToken); + } + + var filesContainer = new SyntaxDeserializer(new TextDecoder(reader.ReadToEnd())).ReadFilesContainer(); + var filesModule = new FileModuleDefinition(SourceOrigin.NoToken); + filesModule.SourceDecls.AddRange( + filesContainer.Files.SelectMany(f => f.TopLevelDecls)); + + return new DfyParseFileResult(null, uri, + filesContainer.Files.Select(f => new Uri(f.Uri)).ToList(), + new BatchErrorReporter(options), filesModule, []); } /// @@ -291,7 +307,7 @@ private static DfyParseFileResult ParseFile(DafnyOptions options, int? version, Parser parser = SetupParser(content, uri, batchErrorReporter, cancellationToken); parser.Parse(); - return new DfyParseFileResult(version, uri, batchErrorReporter, parser.theModule, parser.SystemModuleModifiers); + return new DfyParseFileResult(version, uri, [], batchErrorReporter, parser.theModule, parser.SystemModuleModifiers); } private static Parser SetupParser(string s /*!*/, Uri uri /*!*/, diff --git a/Source/DafnyCore/AST/Members/Field.cs b/Source/DafnyCore/AST/Members/Field.cs index 1902b7c9cb7..b2da0e31b44 100644 --- a/Source/DafnyCore/AST/Members/Field.cs +++ b/Source/DafnyCore/AST/Members/Field.cs @@ -29,7 +29,7 @@ public Field(IOrigin origin, Name name, bool isGhost, Type type, Attributes attr } public Field(IOrigin origin, Name name, bool hasStaticKeyword, bool isGhost, bool isMutable, bool isUserMutable, Type type, Attributes attributes) - : base(origin, name, hasStaticKeyword, isGhost, attributes, false) { + : base(origin, name, hasStaticKeyword, isGhost, attributes) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(type != null); diff --git a/Source/DafnyCore/AST/Members/Function.cs b/Source/DafnyCore/AST/Members/Function.cs index 8f2cb901e92..7060c13f423 100644 --- a/Source/DafnyCore/AST/Members/Function.cs +++ b/Source/DafnyCore/AST/Members/Function.cs @@ -113,8 +113,6 @@ public Type OriginalResultTypeWithRenamings() { public IOrigin /*?*/ ByMethodTok; // null iff ByMethodBody is null public BlockStmt /*?*/ ByMethodBody; [FilledInDuringResolution] public Method /*?*/ ByMethodDecl; // if ByMethodBody is non-null - public bool SignatureIsOmitted => SignatureEllipsis != null; // is "false" for all Function objects that survive into resolution - public readonly IOrigin SignatureEllipsis; public Function OverriddenFunction; public Function Original => OverriddenFunction == null ? this : OverriddenFunction.Original; public override bool IsOverrideThatAddsBody => base.IsOverrideThatAddsBody && Body != null; @@ -232,7 +230,7 @@ public Function(IOrigin range, Name name, bool hasStaticKeyword, bool isGhost, b List req, Specification reads, List ens, Specification decreases, Expression/*?*/ body, IOrigin/*?*/ byMethodTok, BlockStmt/*?*/ byMethodBody, Attributes attributes, IOrigin/*?*/ signatureEllipsis) - : base(range, name, hasStaticKeyword, isGhost, attributes, signatureEllipsis != null, typeArgs, ins, req, ens, decreases) { + : base(range, name, hasStaticKeyword, isGhost, attributes, signatureEllipsis, typeArgs, ins, req, ens, reads, decreases) { Contract.Requires(Origin != null); Contract.Requires(name != null); @@ -247,11 +245,9 @@ public Function(IOrigin range, Name name, bool hasStaticKeyword, bool isGhost, b this.IsFueled = false; // Defaults to false. Only set to true if someone mentions this function in a fuel annotation this.Result = result; this.ResultType = result != null ? result.Type : resultType; - this.Reads = reads; this.Body = body; this.ByMethodTok = byMethodTok; this.ByMethodBody = byMethodBody; - this.SignatureEllipsis = signatureEllipsis; this.IsOpaque = isOpaque || Attributes.Contains(attributes, "opaque"); if (attributes != null) { @@ -535,7 +531,7 @@ public void AutoRevealDependencies(AutoRevealFunctionDependencies rewriter, Dafn object autoRevealDepsVal = null; bool autoRevealDeps = Attributes.ContainsMatchingValue(Attributes, "autoRevealDependencies", - ref autoRevealDepsVal, new List { + ref autoRevealDepsVal, new HashSet { Attributes.MatchingValueOption.Bool, Attributes.MatchingValueOption.Int }, s => reporter.Error(MessageSource.Rewriter, ErrorLevel.Error, Origin, s)); diff --git a/Source/DafnyCore/AST/Members/MemberDecl.cs b/Source/DafnyCore/AST/Members/MemberDecl.cs index 98ffea0414e..9b8924cd3d4 100644 --- a/Source/DafnyCore/AST/Members/MemberDecl.cs +++ b/Source/DafnyCore/AST/Members/MemberDecl.cs @@ -67,10 +67,10 @@ protected MemberDecl(Cloner cloner, MemberDecl original) : base(cloner, original this.isGhost = original.isGhost; } - protected MemberDecl(IOrigin origin, Name name, bool hasStaticKeyword, bool isGhost, Attributes attributes, bool isRefining) - : base(origin, name, attributes, isRefining) { + [SyntaxConstructor] + protected MemberDecl(IOrigin origin, Name nameNode, bool hasStaticKeyword, bool isGhost, Attributes attributes) + : base(origin, nameNode, attributes) { Contract.Requires(origin != null); - Contract.Requires(name != null); this.hasStaticKeyword = hasStaticKeyword; this.isGhost = isGhost; } diff --git a/Source/DafnyCore/AST/Members/Method.cs b/Source/DafnyCore/AST/Members/Method.cs index a012816966b..a36ad00f219 100644 --- a/Source/DafnyCore/AST/Members/Method.cs +++ b/Source/DafnyCore/AST/Members/Method.cs @@ -29,8 +29,6 @@ static Method() { Concat(Req).Concat(Ens).Concat(Reads.Expressions).Concat(Mod.Expressions); public override IEnumerable PreResolveChildren => Children; public override string WhatKind => "method"; - public bool SignatureIsOmitted { get { return SignatureEllipsis != null; } } - public readonly IOrigin SignatureEllipsis; public readonly bool IsByMethod; public bool MustReverify; public bool IsEntryPoint = false; @@ -124,14 +122,13 @@ public Method(Cloner cloner, Method original) : base(cloner, original) { this.Outs = original.Outs.ConvertAll(p => cloner.CloneFormal(p, false)); } - this.Reads = cloner.CloneSpecFrameExpr(original.Reads); this.Mod = cloner.CloneSpecFrameExpr(original.Mod); this.Body = cloner.CloneMethodBody(original); - this.SignatureEllipsis = original.SignatureEllipsis; this.IsByMethod = original.IsByMethod; } - public Method(IOrigin origin, Name name, + [SyntaxConstructor] + public Method(IOrigin origin, Name nameNode, bool hasStaticKeyword, bool isGhost, [Captured] List typeArgs, [Captured] List ins, [Captured] List outs, @@ -143,10 +140,9 @@ public Method(IOrigin origin, Name name, [Captured] BlockStmt body, Attributes attributes, IOrigin signatureEllipsis, bool isByMethod = false) - : base(origin, name, hasStaticKeyword, isGhost, attributes, signatureEllipsis != null, - typeArgs, ins, req, ens, decreases) { + : base(origin, nameNode, hasStaticKeyword, isGhost, attributes, signatureEllipsis, + typeArgs, ins, req, ens, reads, decreases) { Contract.Requires(origin != null); - Contract.Requires(name != null); Contract.Requires(cce.NonNullElements(typeArgs)); Contract.Requires(cce.NonNullElements(ins)); Contract.Requires(cce.NonNullElements(outs)); @@ -156,10 +152,8 @@ public Method(IOrigin origin, Name name, Contract.Requires(cce.NonNullElements(ens)); Contract.Requires(decreases != null); this.Outs = outs; - this.Reads = reads; this.Mod = mod; Body = body; - this.SignatureEllipsis = signatureEllipsis; this.IsByMethod = isByMethod; MustReverify = false; } @@ -450,7 +444,7 @@ public void AutoRevealDependencies(AutoRevealFunctionDependencies Rewriter, Dafn object autoRevealDepsVal = null; bool autoRevealDeps = Attributes.ContainsMatchingValue(Attributes, "autoRevealDependencies", - ref autoRevealDepsVal, new List { + ref autoRevealDepsVal, new HashSet { Attributes.MatchingValueOption.Bool, Attributes.MatchingValueOption.Int }, s => Reporter.Error(MessageSource.Rewriter, ErrorLevel.Error, Origin, s)); diff --git a/Source/DafnyCore/AST/Members/MethodOrFunction.cs b/Source/DafnyCore/AST/Members/MethodOrFunction.cs index 8421c051b8f..615c55db11d 100644 --- a/Source/DafnyCore/AST/Members/MethodOrFunction.cs +++ b/Source/DafnyCore/AST/Members/MethodOrFunction.cs @@ -1,3 +1,4 @@ +#nullable enable using System.Collections.Generic; using System.CommandLine; using System.Linq; @@ -22,15 +23,25 @@ static MethodOrFunction() { public readonly Specification Decreases; public readonly List Ins; - protected MethodOrFunction(IOrigin origin, Name name, bool hasStaticKeyword, bool isGhost, - Attributes attributes, bool isRefining, List typeArgs, List ins, + public bool SignatureIsOmitted => // is "false" for all Function objects that survive into resolution + SignatureEllipsis != null; + + public readonly IOrigin? SignatureEllipsis; + public override bool IsRefining => SignatureIsOmitted; + + [SyntaxConstructor] + protected MethodOrFunction(IOrigin origin, Name nameNode, bool hasStaticKeyword, bool isGhost, + Attributes attributes, IOrigin signatureEllipsis, List typeArgs, List ins, List req, List ens, + Specification reads, Specification decreases) - : base(origin, name, hasStaticKeyword, isGhost, attributes, isRefining) { + : base(origin, nameNode, hasStaticKeyword, isGhost, attributes) { TypeArgs = typeArgs; + this.SignatureEllipsis = signatureEllipsis; Req = req; Decreases = decreases; + Reads = reads; Ens = ens; Ins = ins; } @@ -40,6 +51,8 @@ protected MethodOrFunction(Cloner cloner, MethodOrFunction original) : base(clon this.Req = original.Req.ConvertAll(cloner.CloneAttributedExpr); this.Decreases = cloner.CloneSpecExpr(original.Decreases); this.Ens = original.Ens.ConvertAll(cloner.CloneAttributedExpr); + this.SignatureEllipsis = original.SignatureEllipsis; + this.Reads = cloner.CloneSpecFrameExpr(original.Reads); this.Ins = original.Ins.ConvertAll(p => cloner.CloneFormal(p, false)); if (cloner.CloneResolvedFields) { this.ContainsHide = original.ContainsHide; @@ -95,8 +108,5 @@ public void ResolveMethodOrFunction(INewOrOldResolver resolver) { // The following check is incomplete, which is a bug. || Ins.Any(f => f.Type.AsSubsetType is not null); - protected MethodOrFunction(SourceOrigin tok, Name name, bool hasStaticKeyword, bool isGhost, Attributes attributes, bool isRefining) : base(tok, name, hasStaticKeyword, isGhost, attributes, isRefining) { - } - public Specification Reads { get; set; } } \ No newline at end of file diff --git a/Source/DafnyCore/AST/Modules/AbstractModuleDecl.cs b/Source/DafnyCore/AST/Modules/AbstractModuleDecl.cs index b41e175cd54..22226e403ef 100644 --- a/Source/DafnyCore/AST/Modules/AbstractModuleDecl.cs +++ b/Source/DafnyCore/AST/Modules/AbstractModuleDecl.cs @@ -22,7 +22,7 @@ public AbstractModuleDecl(Cloner cloner, AbstractModuleDecl original, ModuleDefi public AbstractModuleDecl(DafnyOptions options, IOrigin origin, ModuleQualifiedId qid, Name name, ModuleDefinition parent, bool opened, List exports, Guid cloneId) - : base(options, origin, name, parent, opened, false, cloneId) { + : base(options, origin, name, parent, opened, cloneId) { Contract.Requires(qid != null && qid.Path.Count > 0); Contract.Requires(exports != null); diff --git a/Source/DafnyCore/AST/Modules/AliasModuleDecl.cs b/Source/DafnyCore/AST/Modules/AliasModuleDecl.cs index acc59427b82..8635cd099a4 100644 --- a/Source/DafnyCore/AST/Modules/AliasModuleDecl.cs +++ b/Source/DafnyCore/AST/Modules/AliasModuleDecl.cs @@ -33,7 +33,7 @@ public AliasModuleDecl(Cloner cloner, AliasModuleDecl original, ModuleDefinition public AliasModuleDecl(DafnyOptions options, SourceOrigin origin, ModuleQualifiedId path, Name name, ModuleDefinition parent, bool opened, List exports, Guid cloneId) - : base(options, origin, name, parent, opened, false, cloneId) { + : base(options, origin, name, parent, opened, cloneId) { Contract.Requires(path != null && path.Path.Count > 0); Contract.Requires(exports != null); Contract.Requires(exports.Count == 0 || path.Path.Count == 1); diff --git a/Source/DafnyCore/AST/Modules/DefaultClassDecl.cs b/Source/DafnyCore/AST/Modules/DefaultClassDecl.cs index 3d4c7ee1f0a..d85aef06037 100644 --- a/Source/DafnyCore/AST/Modules/DefaultClassDecl.cs +++ b/Source/DafnyCore/AST/Modules/DefaultClassDecl.cs @@ -1,3 +1,4 @@ +#nullable enable using System.Collections.Generic; using System.Diagnostics.Contracts; using System.Linq; @@ -9,10 +10,17 @@ public class DefaultClassDecl : TopLevelDeclWithMembers, RevealableTypeDecl { public override bool AcceptThis => false; public TopLevelDecl AsTopLevelDecl => this; - public TypeDeclSynonymInfo SynonymInfo { get; set; } + public TypeDeclSynonymInfo? SynonymInfo { get; set; } + + [SyntaxConstructor] + public DefaultClassDecl(IOrigin origin, Name nameNode, Attributes? attributes, + List typeArgs, ModuleDefinition enclosingModuleDefinition, + List members, List? traits = null) + : base(origin, nameNode, enclosingModuleDefinition, typeArgs, members, attributes, traits) { + } public DefaultClassDecl(ModuleDefinition module, [Captured] List members) - : base(SourceOrigin.NoToken, new Name("_default"), module, [], members, null, false, null) { + : base(SourceOrigin.NoToken, new Name("_default"), module, [], members, null, null) { Contract.Requires(module != null); Contract.Requires(cce.NonNullElements(members)); this.NewSelfSynonym(); diff --git a/Source/DafnyCore/AST/Modules/FileModuleDefinition.cs b/Source/DafnyCore/AST/Modules/FileModuleDefinition.cs index 551e146e0e6..f80bfc7234a 100644 --- a/Source/DafnyCore/AST/Modules/FileModuleDefinition.cs +++ b/Source/DafnyCore/AST/Modules/FileModuleDefinition.cs @@ -3,6 +3,8 @@ namespace Microsoft.Dafny; + + /// /// This is a temporary container of everything declared at the top level of a file, including include directives. /// After parsing, the contents of this 'module' are moved into the default module. @@ -12,8 +14,8 @@ namespace Microsoft.Dafny; public class FileModuleDefinition : ModuleDefinition { public List Includes { get; } = []; - public FileModuleDefinition(IOrigin token) : - base(token, new Name("_module"), [], + public FileModuleDefinition(IOrigin origin) : + base(origin, new Name("_module"), [], ModuleKindEnum.Concrete, false, null, null, null) { { } diff --git a/Source/DafnyCore/AST/Modules/LiteralModuleDecl.cs b/Source/DafnyCore/AST/Modules/LiteralModuleDecl.cs index fd3a12c22ce..cdb4a9e668a 100644 --- a/Source/DafnyCore/AST/Modules/LiteralModuleDecl.cs +++ b/Source/DafnyCore/AST/Modules/LiteralModuleDecl.cs @@ -45,7 +45,7 @@ public LiteralModuleDecl(Cloner cloner, LiteralModuleDecl original, ModuleDefini } public LiteralModuleDecl(DafnyOptions options, ModuleDefinition module, ModuleDefinition parent, Guid cloneId) - : base(options, module.Origin, module.NameNode, parent, false, false, cloneId) { + : base(options, module.Origin, module.NameNode, parent, false, cloneId) { ModuleDef = module; BodyStartTok = module.BodyStartTok; module.EnclosingLiteralModuleDecl = this; diff --git a/Source/DafnyCore/AST/Modules/ModuleDecl.cs b/Source/DafnyCore/AST/Modules/ModuleDecl.cs index 658ed86ba8c..2a9eaeaf4f1 100644 --- a/Source/DafnyCore/AST/Modules/ModuleDecl.cs +++ b/Source/DafnyCore/AST/Modules/ModuleDecl.cs @@ -45,8 +45,8 @@ protected ModuleDecl(Cloner cloner, ModuleDecl original, ModuleDefinition parent CloneId = original.CloneId; } - protected ModuleDecl(DafnyOptions options, IOrigin origin, Name name, ModuleDefinition parent, bool opened, bool isRefining, Guid cloneId) - : base(origin, name, parent, [], null, isRefining) { + protected ModuleDecl(DafnyOptions options, IOrigin origin, Name name, ModuleDefinition parent, bool opened, Guid cloneId) + : base(origin, name, parent, [], null) { Options = options; Height = -1; Signature = null; diff --git a/Source/DafnyCore/AST/Modules/ModuleDefinition.cs b/Source/DafnyCore/AST/Modules/ModuleDefinition.cs index 7582f42ae06..53f623c7569 100644 --- a/Source/DafnyCore/AST/Modules/ModuleDefinition.cs +++ b/Source/DafnyCore/AST/Modules/ModuleDefinition.cs @@ -68,6 +68,7 @@ public string FullName { } public readonly List PrefixIds; // The qualified module name, except the last segment when a // nested module declaration is outside its enclosing module + [BackEdge] public ModuleDefinition EnclosingModule; // readonly, except can be changed by resolver for prefix-named modules when the real parent is discovered public Attributes Attributes { get; set; } public string WhatKind => "module definition"; @@ -156,14 +157,14 @@ public ModuleDefinition(Cloner cloner, ModuleDefinition original) : base(cloner, } } - public ModuleDefinition(IOrigin tok, Name name, List prefixIds, ModuleKindEnum moduleKind, bool isFacade, - Implements implements, ModuleDefinition parent, Attributes attributes) : base(tok) { - Contract.Requires(tok != null); + public ModuleDefinition(IOrigin origin, Name name, List prefixIds, ModuleKindEnum moduleKind, bool isFacade, + Implements implements, ModuleDefinition enclosingModule, Attributes attributes) : base(origin) { + Contract.Requires(origin != null); Contract.Requires(name != null); this.NameNode = name; this.PrefixIds = prefixIds; this.Attributes = attributes; - this.EnclosingModule = parent; + this.EnclosingModule = enclosingModule; this.Implements = implements; this.ModuleKind = moduleKind; this.IsFacade = isFacade; @@ -1039,7 +1040,7 @@ bool InheritsFromObject(TraitDecl traitDecl) { traitsProgress[traitDecl] = false; // indicate that traitDecl is currently being visited var inheritsFromObject = traitDecl.IsObjectTrait; - foreach (var parent in traitDecl.ParentTraits) { + foreach (var parent in traitDecl.Traits) { if (parent is UserDefinedType udt) { if (ResolveNamePath(udt.NamePath) is TraitDecl parentTrait) { if (parentTrait.EnclosingModuleDefinition == this) { diff --git a/Source/DafnyCore/AST/Modules/ModuleExportDecl.cs b/Source/DafnyCore/AST/Modules/ModuleExportDecl.cs index b8be14a1370..86e877f79d4 100644 --- a/Source/DafnyCore/AST/Modules/ModuleExportDecl.cs +++ b/Source/DafnyCore/AST/Modules/ModuleExportDecl.cs @@ -10,6 +10,7 @@ namespace Microsoft.Dafny; /// Represents the exports of a module. /// public class ModuleExportDecl : ModuleDecl, ICanFormat { + public override bool IsRefining { get; } public readonly bool IsDefault; public List Exports; // list of TopLevelDecl that are included in the export public List Extends; // list of exports that are extended @@ -29,7 +30,6 @@ public ModuleExportDecl(Cloner cloner, ModuleExportDecl original, ModuleDefiniti Extends = original.Extends.Select(cloner.Origin).ToList(); ProvideAll = original.ProvideAll; RevealAll = original.RevealAll; - IsRefining = original.IsRefining; IsDefault = original.IsDefault; ThisScope = new VisibilityScope(FullSanitizedName); SetupDefaultSignature(); @@ -38,8 +38,9 @@ public ModuleExportDecl(Cloner cloner, ModuleExportDecl original, ModuleDefiniti public ModuleExportDecl(DafnyOptions options, IOrigin origin, Name name, ModuleDefinition parent, List exports, List extends, bool provideAll, bool revealAll, bool isDefault, bool isRefining, Guid cloneId) - : base(options, origin, name, parent, false, isRefining, cloneId) { + : base(options, origin, name, parent, false, cloneId) { Contract.Requires(exports != null); + IsRefining = isRefining; IsDefault = isDefault; Exports = exports; Extends = extends; diff --git a/Source/DafnyCore/AST/SourceOrigin.cs b/Source/DafnyCore/AST/SourceOrigin.cs index c0660132417..64b0b30afb3 100644 --- a/Source/DafnyCore/AST/SourceOrigin.cs +++ b/Source/DafnyCore/AST/SourceOrigin.cs @@ -16,6 +16,7 @@ public class SourceOrigin : IOrigin, IComparable { public bool InclusiveEnd => endToken != null; public bool IncludesRange => true; + [SyntaxConstructor] public SourceOrigin(Token startToken, Token? endToken, Token? center = null) { this.endToken = endToken; StartToken = startToken; diff --git a/Source/DafnyCore/AST/Statements/BlockStmt.cs b/Source/DafnyCore/AST/Statements/BlockStmt.cs index d43fa0ef971..9e959bc64d6 100644 --- a/Source/DafnyCore/AST/Statements/BlockStmt.cs +++ b/Source/DafnyCore/AST/Statements/BlockStmt.cs @@ -15,6 +15,11 @@ protected BlockStmt(Cloner cloner, BlockStmt original) : base(cloner, original) Body = original.Body.Select(stmt => cloner.CloneStmt(stmt, false)).ToList(); } + [SyntaxConstructor] + public BlockStmt(IOrigin origin, Attributes attributes, List body) : base(origin, attributes) { + Body = body; + } + public BlockStmt(IOrigin origin, [Captured] List body) : base(origin) { Contract.Requires(origin != null); diff --git a/Source/DafnyCore/AST/Statements/ControlFlow/Label.cs b/Source/DafnyCore/AST/Statements/ControlFlow/Label.cs index 7558c191e20..c5ed26e11f5 100644 --- a/Source/DafnyCore/AST/Statements/ControlFlow/Label.cs +++ b/Source/DafnyCore/AST/Statements/ControlFlow/Label.cs @@ -13,9 +13,9 @@ public string AssignUniqueId(FreshIdGenerator idGen) { } return uniqueId; } - public Label(IOrigin tok, string/*?*/ label) { + public Label(IOrigin tok, string/*?*/ name) { Contract.Requires(tok != null); Tok = tok; - Name = label; + Name = name; } } \ No newline at end of file diff --git a/Source/DafnyCore/AST/Statements/Statement.cs b/Source/DafnyCore/AST/Statements/Statement.cs index 7e5e09184e1..bd3720c3513 100644 --- a/Source/DafnyCore/AST/Statements/Statement.cs +++ b/Source/DafnyCore/AST/Statements/Statement.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -6,12 +7,12 @@ namespace Microsoft.Dafny; public abstract class Statement : RangeNode, IAttributeBearingDeclaration { - public Token PostLabelToken { get; set; } + public Token? PostLabelToken { get; set; } public int ScopeDepth { get; set; } - public LList public static VarDeclStmt CreateLocalVariable(IOrigin tok, string name, Expression value) { - Contract.Requires(tok != null); - Contract.Requires(name != null); - Contract.Requires(value != null); var variable = new LocalVariable(tok, name, value.Type, false); variable.type = value.Type; Expression variableExpr = new IdentifierExpr(tok, variable); diff --git a/Source/DafnyCore/AST/Statements/Verification/AssertLabel.cs b/Source/DafnyCore/AST/Statements/Verification/AssertLabel.cs index cf622067d81..de49b0a83d3 100644 --- a/Source/DafnyCore/AST/Statements/Verification/AssertLabel.cs +++ b/Source/DafnyCore/AST/Statements/Verification/AssertLabel.cs @@ -7,9 +7,9 @@ public class AssertLabel : Label { [FilledInDuringTranslation] public Boogie.Expr E; - public AssertLabel(IOrigin tok, string label) - : base(tok, label) { + public AssertLabel(IOrigin tok, string name) + : base(tok, name) { Contract.Requires(tok != null); - Contract.Requires(label != null); + Contract.Requires(name != null); } } \ No newline at end of file diff --git a/Source/DafnyCore/AST/Statements/Verification/AssertStmt.cs b/Source/DafnyCore/AST/Statements/Verification/AssertStmt.cs index 42a619d2520..721b773cce7 100644 --- a/Source/DafnyCore/AST/Statements/Verification/AssertStmt.cs +++ b/Source/DafnyCore/AST/Statements/Verification/AssertStmt.cs @@ -1,3 +1,4 @@ +#nullable enable using System.Collections.Generic; using System.Diagnostics.Contracts; using Microsoft.Dafny.Auditor; @@ -5,7 +6,7 @@ namespace Microsoft.Dafny; public class AssertStmt : PredicateStmt, ICloneable, ICanFormat { - public readonly AssertLabel Label; + public readonly AssertLabel? Label; public AssertStmt Clone(Cloner cloner) { return new AssertStmt(cloner, this); @@ -15,7 +16,7 @@ public AssertStmt(Cloner cloner, AssertStmt original) : base(cloner, original) { Label = original.Label == null ? null : new AssertLabel(cloner.Origin(original.Label.Tok), original.Label.Name); } - public static AssertStmt CreateErrorAssert(INode node, string message, Expression guard = null) { + public static AssertStmt CreateErrorAssert(INode node, string message, Expression? guard = null) { var errorMessage = new StringLiteralExpr(node.Origin, message, true); errorMessage.Type = new SeqType(Type.Char); var attr = new Attributes("error", [errorMessage], null); @@ -25,8 +26,9 @@ public static AssertStmt CreateErrorAssert(INode node, string message, Expressio return assertFalse; } - public AssertStmt(IOrigin origin, Expression expr, AssertLabel/*?*/ label, Attributes attrs) - : base(origin, expr, attrs) { + [SyntaxConstructor] + public AssertStmt(IOrigin origin, Expression expr, AssertLabel? label, Attributes attributes) + : base(origin, expr, attributes) { Contract.Requires(origin != null); Contract.Requires(expr != null); Label = label; @@ -67,7 +69,7 @@ public override void GenResolve(INewOrOldResolver resolver, ResolutionContext co } if (this.HasUserAttribute("only", out var attribute)) { - resolver.Reporter.Warning(MessageSource.Verifier, ResolutionErrors.ErrorId.r_assert_only_assumes_others.ToString(), attribute.Origin, + resolver.Reporter.Warning(MessageSource.Verifier, ResolutionErrors.ErrorId.r_assert_only_assumes_others.ToString(), attribute!.Origin, "Assertion with {:only} temporarily transforms other assertions into assumptions"); if (attribute.Args.Count >= 1 && attribute.Args[0] is LiteralExpr { Value: string value } @@ -86,7 +88,7 @@ public bool HasAssertOnlyAttribute(out AssertOnlyKind assertOnlyKind) { return false; } - if (attribute.Args.Count != 1 || attribute.Args[0] is not LiteralExpr { Value: var value }) { + if (attribute!.Args.Count != 1 || attribute.Args[0] is not LiteralExpr { Value: var value }) { return true; } diff --git a/Source/DafnyCore/AST/Statements/Verification/AssumeStmt.cs b/Source/DafnyCore/AST/Statements/Verification/AssumeStmt.cs index bf5b58098a1..cbe324e58e6 100644 --- a/Source/DafnyCore/AST/Statements/Verification/AssumeStmt.cs +++ b/Source/DafnyCore/AST/Statements/Verification/AssumeStmt.cs @@ -12,8 +12,8 @@ public AssumeStmt Clone(Cloner cloner) { public AssumeStmt(Cloner cloner, AssumeStmt original) : base(cloner, original) { } - public AssumeStmt(IOrigin origin, Expression expr, Attributes attrs) - : base(origin, expr, attrs) { + public AssumeStmt(IOrigin origin, Expression expr, Attributes attributes) + : base(origin, expr, attributes) { Contract.Requires(origin != null); Contract.Requires(expr != null); } diff --git a/Source/DafnyCore/AST/Statements/Verification/ExpectStmt.cs b/Source/DafnyCore/AST/Statements/Verification/ExpectStmt.cs index 825a306b24f..036f121d345 100644 --- a/Source/DafnyCore/AST/Statements/Verification/ExpectStmt.cs +++ b/Source/DafnyCore/AST/Statements/Verification/ExpectStmt.cs @@ -14,8 +14,8 @@ public ExpectStmt(Cloner cloner, ExpectStmt original) : base(cloner, original) { Message = cloner.CloneExpr(original.Message); } - public ExpectStmt(IOrigin origin, Expression expr, Expression message, Attributes attrs) - : base(origin, expr, attrs) { + public ExpectStmt(IOrigin origin, Expression expr, Expression message, Attributes attributes) + : base(origin, expr, attributes) { Contract.Requires(origin != null); Contract.Requires(expr != null); this.Message = message; diff --git a/Source/DafnyCore/AST/Statements/Verification/PredicateStmt.cs b/Source/DafnyCore/AST/Statements/Verification/PredicateStmt.cs index dc8267241df..f66c3040bd3 100644 --- a/Source/DafnyCore/AST/Statements/Verification/PredicateStmt.cs +++ b/Source/DafnyCore/AST/Statements/Verification/PredicateStmt.cs @@ -13,8 +13,9 @@ protected PredicateStmt(Cloner cloner, PredicateStmt original) : base(cloner, or Expr = cloner.CloneExpr(original.Expr); } - protected PredicateStmt(IOrigin origin, Expression expr, Attributes attrs) - : base(origin, attrs) { + [SyntaxConstructor] + protected PredicateStmt(IOrigin origin, Expression expr, Attributes attributes) + : base(origin, attributes) { Contract.Requires(origin != null); Contract.Requires(expr != null); this.Expr = expr; diff --git a/Source/DafnyCore/AST/SyntaxDeserializer/Generated.cs b/Source/DafnyCore/AST/SyntaxDeserializer/Generated.cs new file mode 100644 index 00000000000..a3a6254cc17 --- /dev/null +++ b/Source/DafnyCore/AST/SyntaxDeserializer/Generated.cs @@ -0,0 +1,317 @@ +using System; +using System.Collections.Generic; + +namespace Microsoft.Dafny { + partial class SyntaxDeserializer { + public Attributes ReadAttributes() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadString(); + var parameter2 = ReadList(() => ReadAbstract()); + var parameter3 = ReadAttributesOption(); + return new Attributes(parameter0, parameter1, parameter2, parameter3); + } + + public Attributes ReadAttributesOption() { + if (ReadIsNull()) { + return default; + } + + return ReadAttributes(); + } + + public LiteralExpr ReadLiteralExpr() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadAbstract(); + return new LiteralExpr(parameter0, parameter1); + } + + public LiteralExpr ReadLiteralExprOption() { + if (ReadIsNull()) { + return default; + } + + return ReadLiteralExpr(); + } + + public AttributedExpression ReadAttributedExpression() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadAssertLabel(); + var parameter2 = ReadAttributes(); + return new AttributedExpression(parameter0, parameter1, parameter2); + } + + public AttributedExpression ReadAttributedExpressionOption() { + if (ReadIsNull()) { + return default; + } + + return ReadAttributedExpression(); + } + + public Label ReadLabel() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadString(); + return new Label(parameter0, parameter1); + } + + public Label ReadLabelOption() { + if (ReadIsNull()) { + return default; + } + + return ReadLabel(); + } + + public AssertLabel ReadAssertLabel() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadString(); + return new AssertLabel(parameter0, parameter1); + } + + public AssertLabel ReadAssertLabelOption() { + if (ReadIsNull()) { + return default; + } + + return ReadAssertLabel(); + } + + public Name ReadName() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadString(); + return new Name(parameter0, parameter1); + } + + public Name ReadNameOption() { + if (ReadIsNull()) { + return default; + } + + return ReadName(); + } + + public TypeParameter ReadTypeParameter() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadName(); + var parameter5 = ReadAttributesOption(); + var parameter2 = ReadTypeParameterTPVarianceSyntax(); + var parameter3 = ReadTypeParameterCharacteristics(); + var parameter4 = ReadList(() => ReadAbstract()); + return new TypeParameter(parameter0, parameter1, parameter2, parameter3, parameter4, parameter5); + } + + public TypeParameter ReadTypeParameterOption() { + if (ReadIsNull()) { + return default; + } + + return ReadTypeParameter(); + } + + public TypeParameterCharacteristics ReadTypeParameterCharacteristics() { + var parameter0 = ReadTypeParameterEqualitySupportValue(); + var parameter1 = ReadTypeAutoInitInfo(); + var parameter2 = ReadBoolean(); + return new TypeParameterCharacteristics(parameter0, parameter1, parameter2); + } + + public TypeParameterCharacteristics ReadTypeParameterCharacteristicsOption() { + if (ReadIsNull()) { + return default; + } + + return ReadTypeParameterCharacteristics(); + } + + private Type.AutoInitInfo ReadTypeAutoInitInfo() { + int ordinal = ReadInt32(); + return (Type.AutoInitInfo)ordinal; + } + + private TypeParameter.EqualitySupportValue ReadTypeParameterEqualitySupportValue() { + int ordinal = ReadInt32(); + return (TypeParameter.EqualitySupportValue)ordinal; + } + + private TypeParameter.TPVarianceSyntax ReadTypeParameterTPVarianceSyntax() { + int ordinal = ReadInt32(); + return (TypeParameter.TPVarianceSyntax)ordinal; + } + + public FrameExpression ReadFrameExpression() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadAbstract(); + var parameter2 = ReadString(); + return new FrameExpression(parameter0, parameter1, parameter2); + } + + public FrameExpression ReadFrameExpressionOption() { + if (ReadIsNull()) { + return default; + } + + return ReadFrameExpression(); + } + + public Formal ReadFormal() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadName(); + var parameter2 = ReadAbstract(); + var parameter4 = ReadBoolean(); + var parameter3 = ReadBoolean(); + var parameter5 = ReadAbstract(); + var parameter6 = ReadAttributes(); + var parameter7 = ReadBoolean(); + var parameter8 = ReadBoolean(); + var parameter9 = ReadBoolean(); + var parameter10 = ReadString(); + return new Formal(parameter0, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7, parameter8, parameter9, parameter10); + } + + public Formal ReadFormalOption() { + if (ReadIsNull()) { + return default; + } + + return ReadFormal(); + } + + public Method ReadMethod() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadName(); + var parameter13 = ReadAttributesOption(); + var parameter2 = ReadBoolean(); + var parameter3 = ReadBoolean(); + var parameter14 = ReadAbstractOption(); + var parameter4 = ReadList(() => ReadTypeParameter()); + var parameter5 = ReadList(() => ReadFormal()); + var parameter7 = ReadList(() => ReadAttributedExpression()); + var parameter10 = ReadList(() => ReadAttributedExpression()); + var parameter8 = ReadSpecification(); + var parameter11 = ReadSpecification(); + var parameter6 = ReadList(() => ReadFormal()); + var parameter9 = ReadSpecification(); + var parameter12 = ReadBlockStmt(); + var parameter15 = ReadBoolean(); + return new Method(parameter0, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6, parameter7, parameter8, parameter9, parameter10, parameter11, parameter12, parameter13, parameter14, parameter15); + } + + public Method ReadMethodOption() { + if (ReadIsNull()) { + return default; + } + + return ReadMethod(); + } + + public AssertStmt ReadAssertStmt() { + var parameter0 = ReadAbstract(); + var parameter3 = ReadAttributesOption(); + var parameter1 = ReadAbstract(); + var parameter2 = ReadAssertLabelOption(); + return new AssertStmt(parameter0, parameter1, parameter2, parameter3); + } + + public AssertStmt ReadAssertStmtOption() { + if (ReadIsNull()) { + return default; + } + + return ReadAssertStmt(); + } + + public BlockStmt ReadBlockStmt() { + var parameter0 = ReadAbstract(); + var parameter1 = ReadAttributesOption(); + var parameter2 = ReadList(() => ReadAbstract()); + return new BlockStmt(parameter0, parameter1, parameter2); + } + + public BlockStmt ReadBlockStmtOption() { + if (ReadIsNull()) { + return default; + } + + return ReadBlockStmt(); + } + + public DefaultClassDecl ReadDefaultClassDecl() { + Microsoft.Dafny.ModuleDefinition parameter4 = null; + var parameter0 = ReadAbstract(); + var parameter1 = ReadName(); + var parameter2 = ReadAttributesOption(); + var parameter3 = ReadList(() => ReadTypeParameter()); + var parameter5 = ReadList(() => ReadAbstract()); + var parameter6 = ReadList(() => ReadAbstract()); + return new DefaultClassDecl(parameter0, parameter1, parameter2, parameter3, parameter4, parameter5, parameter6); + } + + public DefaultClassDecl ReadDefaultClassDeclOption() { + if (ReadIsNull()) { + return default; + } + + return ReadDefaultClassDecl(); + } + + private object ReadObject(System.Type actualType) { + if (actualType == typeof(Attributes)) { + return ReadAttributes(); + } + + if (actualType == typeof(LiteralExpr)) { + return ReadLiteralExpr(); + } + + if (actualType == typeof(AttributedExpression)) { + return ReadAttributedExpression(); + } + + if (actualType == typeof(Label)) { + return ReadLabel(); + } + + if (actualType == typeof(AssertLabel)) { + return ReadAssertLabel(); + } + + if (actualType == typeof(Name)) { + return ReadName(); + } + + if (actualType == typeof(TypeParameter)) { + return ReadTypeParameter(); + } + + if (actualType == typeof(TypeParameterCharacteristics)) { + return ReadTypeParameterCharacteristics(); + } + + if (actualType == typeof(FrameExpression)) { + return ReadFrameExpression(); + } + + if (actualType == typeof(Formal)) { + return ReadFormal(); + } + + if (actualType == typeof(Method)) { + return ReadMethod(); + } + + if (actualType == typeof(AssertStmt)) { + return ReadAssertStmt(); + } + + if (actualType == typeof(BlockStmt)) { + return ReadBlockStmt(); + } + + if (actualType == typeof(DefaultClassDecl)) { + return ReadDefaultClassDecl(); + } + + throw new Exception(); + } + } +} \ No newline at end of file diff --git a/Source/DafnyCore/AST/SyntaxDeserializer/HandWritten.cs b/Source/DafnyCore/AST/SyntaxDeserializer/HandWritten.cs new file mode 100644 index 00000000000..812da7f7d44 --- /dev/null +++ b/Source/DafnyCore/AST/SyntaxDeserializer/HandWritten.cs @@ -0,0 +1,181 @@ +#nullable enable + +using System; +using System.Collections.Generic; +using System.Linq; + +namespace Microsoft.Dafny; + +/// +/// When using Dafny as a downstream tool, it can be useful to pass already parsed Dafny programs to Dafny, +/// since that allows filling the AST with source locations from other sources. +/// +/// To enable this workflow for programs not written in C#, +/// Dafny supports consuming parsed programs from a serialized format. +/// +/// This class allows reading Dafny programs that are encoded based on the schema defined in Source/Scripts/Syntax.cs.schema +/// +/// The exact encoding can be varied using the instance of IDecoder, but it must adhere to these constraints: +/// - Instances of classes must contain the fields from the schema, in the order from the schema +/// - Arrays must specify their length first +/// - When encoding a field of an abstract class, +/// the concrete type of the field value must be specified before encoding its own fields. +/// +/// +public partial class SyntaxDeserializer(IDecoder decoder) { + private Uri? uri; + + private Specification ReadSpecification() where T : Node { + var parameter0 = ReadAbstract(); + if (typeof(T) == typeof(FrameExpression)) { + var parameter1 = ReadList(() => (T)(object)ReadFrameExpression()); + var parameter2 = ReadAttributesOption(); + return new Specification(parameter0, parameter1, parameter2); + } else { + var parameter1 = ReadList(() => (T)(object)ReadAbstract()); + var parameter2 = ReadAttributesOption(); + return new Specification(parameter0, parameter1, parameter2); + } + } + + private List? ReadListOption(Func readElement) { + var isNull = decoder.ReadIsNull(); + if (isNull) { + return null; + } + + return ReadArray(readElement).ToList(); + } + + private List ReadList(Func readElement) { + return ReadArray(readElement).ToList(); + } + + public Token ReadTokenOption() { + return ReadToken(); + } + + public FilesContainer ReadFilesContainer() { + var files = ReadList(() => ReadFileStart()); + return new FilesContainer(files); + } + + public FileStart ReadFileStart() { + var uri = ReadString(); + this.uri = new Uri(uri); + var topLevelDecls = ReadList(() => ReadAbstract()); + return new FileStart(uri, topLevelDecls); + } + + public Token ReadToken() { + var parameter0 = ReadInt32(); + var parameter1 = ReadInt32(); + return new Token(parameter0, parameter1) { + Uri = uri + }; + } + + private T[] ReadArray(Func readElement) { + var length = decoder.ReadInt32(); + var array = new T[length]; + for (int i = 0; i < length; i++) { + array.SetValue(readElement(), i); + } + return array; + } + + private T Value() { + return DeserializeGeneric(); + } + + public T ReadAbstractOption() { + + var isNull = decoder.ReadIsNull(); + if (isNull) { + return default!; + } + + return ReadAbstract(); + } + + public T ReadAbstract() { + var typeName = decoder.ReadQualifiedName(); + var actualType = System.Type.GetType("Microsoft.Dafny." + typeName) ?? + System.Type.GetType("System." + typeName) ?? + throw new Exception($"Type not found: {typeName}, expected type {typeof(T).Name}, position {decoder.Position}"); + return DeserializeGeneric(actualType); + } + + public bool ReadIsNull() { + return decoder.ReadIsNull(); + } + + public bool ReadBool() { + return decoder.ReadBool(); + } + + public bool ReadBoolean() { + return decoder.ReadBool(); + } + + public SourceOrigin ReadSourceOrigin() { + var start = ReadToken(); + var end = ReadToken(); + var center = ReadToken(); + return new SourceOrigin(start, end, center); + } + + public string? ReadStringOption() { + var isNull = decoder.ReadIsNull(); + if (isNull) { + return default; + } + return decoder.ReadString(); + } + + public string ReadString() { + return decoder.ReadString(); + } + + public T DeserializeGeneric() { + return DeserializeGeneric(typeof(T)); + } + + public T DeserializeGeneric(System.Type actualType) { + + if (actualType == typeof(string)) { + return (T)(object)decoder.ReadString(); + } + + if (actualType == typeof(bool)) { + return (T)(object)decoder.ReadBool(); + } + + if (actualType == typeof(int)) { + return (T)(object)decoder.ReadInt32(); + } + + if (actualType == typeof(SourceOrigin)) { + return (T)(object)ReadSourceOrigin(); + } + + if (actualType == typeof(Token)) { + return (T)(object)ReadToken(); + } + + return (T)ReadObject(actualType); + } + + private int ReadInt32() { + return decoder.ReadInt32(); + } +} + +public class FilesContainer(List files) { + public List Files { get; } = files; +} + +public class FileStart(string uri, List topLevelDecls) { + public string Uri { get; } = uri; + public List TopLevelDecls { get; } = topLevelDecls; +} \ No newline at end of file diff --git a/Source/DafnyCore/AST/SyntaxDeserializer/IDecoder.cs b/Source/DafnyCore/AST/SyntaxDeserializer/IDecoder.cs new file mode 100644 index 00000000000..6ade4578d22 --- /dev/null +++ b/Source/DafnyCore/AST/SyntaxDeserializer/IDecoder.cs @@ -0,0 +1,12 @@ +using System.IO; + +namespace Microsoft.Dafny; + +public interface IDecoder { + string Position { get; } + int ReadInt32(); + bool ReadBool(); + bool ReadIsNull(); + string ReadString(); + string ReadQualifiedName(); +} \ No newline at end of file diff --git a/Source/DafnyCore/AST/SyntaxDeserializer/TextDecoder.cs b/Source/DafnyCore/AST/SyntaxDeserializer/TextDecoder.cs new file mode 100644 index 00000000000..74b8b9c0100 --- /dev/null +++ b/Source/DafnyCore/AST/SyntaxDeserializer/TextDecoder.cs @@ -0,0 +1,117 @@ +using System; +using System.Linq; +using System.Text; + +namespace Microsoft.Dafny; + +/// +/// A textual serialization format can be used to make it easier to debug serialization issues +/// +public class TextDecoder(string input) : IDecoder { + private const int IntStopCharacter = ';'; + private int position; + + public string Position => position.ToString(); + public string Input => input; + + public int ReadInt32() { + var start = position; + while (position < input.Length && input[position] != IntStopCharacter) { + position++; + } + + var end = position; + position++; + + ReadSeparator(); + string chars = input.Substring(start, end - start); + return int.Parse(chars); + } + + private void ReadSeparator() { + if (input[position] != ' ') { + throw Error("a space"); + } + + position++; + } + + private Exception Error(string expectation) { + throw new Exception($"Expected {expectation} at {position} but found {Remainder.Take(5)}"); + } + + public bool ReadBool() { + if (CheckAndAdvance("true")) { + return true; + } + if (CheckAndAdvance("false")) { + return false; + } + + throw Error("true or false"); + } + + public bool ReadIsNull() { + return CheckAndAdvance("null"); + } + + private bool CheckAndAdvance(string keyword) { + if (input.Substring(position, keyword.Length) == keyword) { + position += keyword.Length; + ReadSeparator(); + return true; + } + + return false; + } + + public string Remainder => input.Substring(position); + + public string ReadString() { + var sb = new StringBuilder(); + bool escaped = false; + + if (input[position] != '"') { + throw Error("a quotation mark"); + } + + position++; + + while (position < input.Length) { + char c = input[position++]; + + if (escaped) { + switch (c) { + case 'n': sb.Append('\n'); break; + case 'r': sb.Append('\r'); break; + case 't': sb.Append('\t'); break; + default: sb.Append(c); break; + } + escaped = false; + } else if (c == '\\') { + escaped = true; + } else if (c == '"') { + break; + } else { + sb.Append(c); + } + } + + ReadSeparator(); + return sb.ToString(); + } + + public string ReadQualifiedName() { + var start = position; + while (position < input.Length) { + var c = input[position]; + if (!char.IsLetterOrDigit(c) && c != '.') { + break; + } + position++; + } + var end = position; + ReadSeparator(); + return input.Substring(start, end - start); + } +} \ No newline at end of file diff --git a/Source/DafnyCore/AST/SystemModuleManager.cs b/Source/DafnyCore/AST/SystemModuleManager.cs index dfd4ad059f7..b7e59dd938f 100644 --- a/Source/DafnyCore/AST/SystemModuleManager.cs +++ b/Source/DafnyCore/AST/SystemModuleManager.cs @@ -93,7 +93,7 @@ public SystemModuleManager(DafnyOptions options) { SystemModule.Height = -1; // the system module doesn't get a height assigned later, so we set it here to something below everything else // create type synonym 'string' var str = new TypeSynonymDecl(SourceOrigin.NoToken, new Name("string"), - new TypeParameter.TypeParameterCharacteristics(TypeParameter.EqualitySupportValue.InferredRequired, Type.AutoInitInfo.CompilableValue, false), + new TypeParameterCharacteristics(TypeParameter.EqualitySupportValue.InferredRequired, Type.AutoInitInfo.CompilableValue, false), [], SystemModule, new SeqType(new CharType()), null); SystemModule.SourceDecls.Add(str); // create subset type 'nat' @@ -101,7 +101,7 @@ public SystemModuleManager(DafnyOptions options) { var natConstraint = Expression.CreateAtMost(Expression.CreateIntLiteral(Token.NoToken, 0), Expression.CreateIdentExpr(bvNat)); var ax = AxiomAttribute(); NatDecl = new SubsetTypeDecl(SourceOrigin.NoToken, new Name("nat"), - new TypeParameter.TypeParameterCharacteristics(TypeParameter.EqualitySupportValue.InferredRequired, Type.AutoInitInfo.CompilableValue, false), + new TypeParameterCharacteristics(TypeParameter.EqualitySupportValue.InferredRequired, Type.AutoInitInfo.CompilableValue, false), [], SystemModule, bvNat, natConstraint, SubsetTypeDecl.WKind.CompiledZero, null, ax); ((RedirectingTypeDecl)NatDecl).ConstraintIsCompilable = true; SystemModule.SourceDecls.Add(NatDecl); @@ -330,7 +330,7 @@ Function CreateMember(string name, Type resultType, Function readsFunction = nul tys = tps.ConvertAll(tp => (Type)(new UserDefinedType(tp))); var id = new BoundVar(tok, "f", new ArrowType(tok, arrowDecl, tys)); var partialArrow = new SubsetTypeDecl(SourceOrigin.NoToken, new Name(ArrowType.PartialArrowTypeName(arity)), - new TypeParameter.TypeParameterCharacteristics(false), tps, SystemModule, + new TypeParameterCharacteristics(false), tps, SystemModule, id, ArrowSubtypeConstraint(tok, id, reads, tps, false), SubsetTypeDecl.WKind.Special, null, DontCompile()); ((RedirectingTypeDecl)partialArrow).ConstraintIsCompilable = false; PartialArrowTypeDecls.Add(arity, partialArrow); @@ -345,7 +345,7 @@ Function CreateMember(string name, Type resultType, Function readsFunction = nul tys = tps.ConvertAll(tp => (Type)(new UserDefinedType(tp))); id = new BoundVar(tok, "f", new UserDefinedType(tok, partialArrow.Name, partialArrow, tys)); var totalArrow = new SubsetTypeDecl(SourceOrigin.NoToken, new Name(ArrowType.TotalArrowTypeName(arity)), - new TypeParameter.TypeParameterCharacteristics(false), tps, SystemModule, + new TypeParameterCharacteristics(false), tps, SystemModule, id, ArrowSubtypeConstraint(tok, id, req, tps, true), SubsetTypeDecl.WKind.Special, null, DontCompile()); ((RedirectingTypeDecl)totalArrow).ConstraintIsCompilable = false; TotalArrowTypeDecls.Add(arity, totalArrow); diff --git a/Source/DafnyCore/AST/Tokens.cs b/Source/DafnyCore/AST/Tokens.cs index 2b3173b2c8b..8427ce11362 100644 --- a/Source/DafnyCore/AST/Tokens.cs +++ b/Source/DafnyCore/AST/Tokens.cs @@ -18,9 +18,10 @@ public class Token : IOrigin { public Token() : this(0, 0) { } - public Token(int linenum, int colnum) { - this.line = linenum; - this.col = colnum; + [SyntaxConstructor] + public Token(int line, int col) { + this.line = line; + this.col = col; this.val = ""; } diff --git a/Source/DafnyCore/AST/TypeDeclarations/AbstractTypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/AbstractTypeDecl.cs index 5662efb1421..d0baf32a32c 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/AbstractTypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/AbstractTypeDecl.cs @@ -4,20 +4,22 @@ namespace Microsoft.Dafny; public class AbstractTypeDecl : TopLevelDeclWithMembers, RevealableTypeDecl, ICanFormat, IHasDocstring { + public override bool IsRefining { get; } public override string WhatKind { get { return "abstract type"; } } public override bool CanBeRevealed() { return true; } - public readonly TypeParameter.TypeParameterCharacteristics Characteristics; + public readonly TypeParameterCharacteristics Characteristics; public bool SupportsEquality { get { return Characteristics.EqualitySupport != TypeParameter.EqualitySupportValue.Unspecified; } } - public AbstractTypeDecl(IOrigin origin, Name name, ModuleDefinition module, TypeParameter.TypeParameterCharacteristics characteristics, + public AbstractTypeDecl(IOrigin origin, Name name, ModuleDefinition module, TypeParameterCharacteristics characteristics, List typeArgs, List parentTraits, List members, Attributes attributes, bool isRefining) - : base(origin, name, module, typeArgs, members, attributes, isRefining, parentTraits) { + : base(origin, name, module, typeArgs, members, attributes, parentTraits) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(module != null); Contract.Requires(typeArgs != null); + IsRefining = isRefining; Characteristics = characteristics; this.NewSelfSynonym(); } diff --git a/Source/DafnyCore/AST/TypeDeclarations/ClassDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/ClassDecl.cs index 9dc90af6308..cf4375eaf7b 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/ClassDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/ClassDecl.cs @@ -12,7 +12,7 @@ public class ClassDecl : ClassLikeDecl { [ContractInvariantMethod] void ObjectInvariant() { Contract.Invariant(cce.NonNullElements(Members)); - Contract.Invariant(ParentTraits != null); + Contract.Invariant(Traits != null); } public ClassDecl(IOrigin origin, Name name, ModuleDefinition module, diff --git a/Source/DafnyCore/AST/TypeDeclarations/ClassLikeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/ClassLikeDecl.cs index bdc617d61b0..e6ea3de72bd 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/ClassLikeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/ClassLikeDecl.cs @@ -5,6 +5,7 @@ namespace Microsoft.Dafny; public abstract class ClassLikeDecl : TopLevelDeclWithMembers, RevealableTypeDecl, ICanFormat, IHasDocstring { + public override bool IsRefining { get; } public NonNullTypeDecl NonNullTypeDecl; // returns non-null value iff IsReferenceTypeDecl public override bool CanBeRevealed() { return true; } @@ -26,10 +27,11 @@ public bool IsObjectTrait { public ClassLikeDecl(IOrigin origin, Name name, ModuleDefinition module, List typeArgs, [Captured] List members, Attributes attributes, bool isRefining, List/*?*/ traits) - : base(origin, name, module, typeArgs, members, attributes, isRefining, traits) { + : base(origin, name, module, typeArgs, members, attributes, traits) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(module != null); + IsRefining = isRefining; Contract.Requires(cce.NonNullElements(typeArgs)); Contract.Requires(cce.NonNullElements(members)); } @@ -70,7 +72,7 @@ public virtual bool SetIndent(int indentBefore, TokenNewIndentCollector formatte Attributes.SetIndents(Attributes, indentBefore, formatter); - foreach (var parent in ParentTraits) { + foreach (var parent in Traits) { formatter.SetTypeIndentation(parent); } diff --git a/Source/DafnyCore/AST/TypeDeclarations/DatatypeCtor.cs b/Source/DafnyCore/AST/TypeDeclarations/DatatypeCtor.cs index 2cae5901581..12507507f82 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/DatatypeCtor.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/DatatypeCtor.cs @@ -25,7 +25,7 @@ void ObjectInvariant() { [FilledInDuringResolution] public List Destructors = []; // includes both implicit (not mentionable in source) and explicit destructors public DatatypeCtor(IOrigin origin, Name name, bool isGhost, [Captured] List formals, Attributes attributes) - : base(origin, name, attributes, false) { + : base(origin, name, attributes) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(cce.NonNullElements(formals)); diff --git a/Source/DafnyCore/AST/TypeDeclarations/DatatypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/DatatypeDecl.cs index 297eb83ab3c..94a9bcbd51e 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/DatatypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/DatatypeDecl.cs @@ -7,6 +7,7 @@ namespace Microsoft.Dafny; public abstract class DatatypeDecl : TopLevelDeclWithMembers, RevealableTypeDecl, ICallable, ICanFormat, IHasDocstring, ICanAutoRevealDependencies { + public override bool IsRefining { get; } public override bool CanBeRevealed() { return true; } public readonly List Ctors; @@ -23,14 +24,14 @@ void ObjectInvariant() { public DatatypeDecl(IOrigin origin, Name name, ModuleDefinition module, List typeArgs, [Captured] List ctors, List parentTraits, List members, Attributes attributes, bool isRefining) - : base(origin, name, module, typeArgs, members, attributes, isRefining, parentTraits) { + : base(origin, name, module, typeArgs, members, attributes, parentTraits) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(module != null); + IsRefining = isRefining; Contract.Requires(cce.NonNullElements(typeArgs)); Contract.Requires(cce.NonNullElements(ctors)); Contract.Requires(cce.NonNullElements(members)); - Contract.Requires((isRefining && ctors.Count == 0) || (!isRefining && 1 <= ctors.Count)); Ctors = ctors; this.NewSelfSynonym(); } diff --git a/Source/DafnyCore/AST/TypeDeclarations/Declaration.cs b/Source/DafnyCore/AST/TypeDeclarations/Declaration.cs index f7ca2d7bf9e..e6d43aa65fd 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/Declaration.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/Declaration.cs @@ -1,3 +1,4 @@ +#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.Contracts; @@ -19,7 +20,7 @@ void ObjectInvariant() { public virtual IOrigin NavigationToken => NameNode.Origin; public string Name => NameNode.Value; - public bool IsRefining; + public virtual bool IsRefining => false; private VisibilityScope opaqueScope = new(); private VisibilityScope revealScope = new(); @@ -32,12 +33,11 @@ protected Declaration(Cloner cloner, Declaration original) : base(cloner, origin Attributes = cloner.CloneAttributes(original.Attributes); } - protected Declaration(IOrigin origin, Name name, Attributes attributes, bool isRefining) : base(origin) { + [SyntaxConstructor] + protected Declaration(IOrigin origin, Name nameNode, Attributes attributes) : base(origin) { Contract.Requires(origin != null); - Contract.Requires(name != null); - this.NameNode = name; + this.NameNode = nameNode; this.Attributes = attributes; - this.IsRefining = isRefining; } public bool HasAxiomAttribute => @@ -108,10 +108,10 @@ public bool IsVisibleInScope(VisibilityScope scope) { return IsRevealedInScope(scope) || opaqueScope.VisibleInScope(scope); } - protected string sanitizedName; + protected string? sanitizedName; public virtual string SanitizedName => sanitizedName ??= NonglobalVariable.SanitizeName(Name); - protected string compileName; + protected string? compileName; public virtual string GetCompileName(DafnyOptions options) { if (compileName == null) { @@ -122,8 +122,8 @@ public virtual string GetCompileName(DafnyOptions options) { return compileName; } - public Attributes Attributes; // readonly, except during class merging in the refinement transformations and when changed by Compiler.MarkCapitalizationConflict - Attributes IAttributeBearingDeclaration.Attributes { + public Attributes? Attributes; // readonly, except during class merging in the refinement transformations and when changed by Compiler.MarkCapitalizationConflict + Attributes? IAttributeBearingDeclaration.Attributes { get => Attributes; set => Attributes = value; } diff --git a/Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs index 2efc6031a1c..33bcae46b9d 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/NewtypeDecl.cs @@ -35,13 +35,13 @@ bool RedirectingTypeDecl.ConstraintIsCompilable { public NewtypeDecl(IOrigin origin, Name name, List typeParameters, ModuleDefinition module, Type baseType, SubsetTypeDecl.WKind witnessKind, Expression witness, List parentTraits, List members, Attributes attributes, bool isRefining) - : base(origin, name, module, typeParameters, members, attributes, isRefining, parentTraits) { + : base(origin, name, module, typeParameters, members, attributes, parentTraits) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(module != null); - Contract.Requires(isRefining ^ (baseType != null)); Contract.Requires((witnessKind == SubsetTypeDecl.WKind.Compiled || witnessKind == SubsetTypeDecl.WKind.Ghost) == (witness != null)); Contract.Requires(members != null); + IsRefining = isRefining; BaseType = baseType; Witness = witness; WitnessKind = witnessKind; @@ -50,7 +50,7 @@ public NewtypeDecl(IOrigin origin, Name name, List typeParameters public NewtypeDecl(IOrigin origin, Name name, List typeParameters, ModuleDefinition module, BoundVar bv, Expression constraint, SubsetTypeDecl.WKind witnessKind, Expression witness, List parentTraits, List members, Attributes attributes, bool isRefining) - : base(origin, name, module, typeParameters, members, attributes, isRefining, parentTraits) { + : base(origin, name, module, typeParameters, members, attributes, parentTraits) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(module != null); @@ -58,12 +58,14 @@ public NewtypeDecl(IOrigin origin, Name name, List typeParameters Contract.Requires((witnessKind == SubsetTypeDecl.WKind.Compiled || witnessKind == SubsetTypeDecl.WKind.Ghost) == (witness != null)); Contract.Requires(members != null); BaseType = bv.Type; + IsRefining = isRefining; Var = bv; Constraint = constraint; Witness = witness; WitnessKind = witnessKind; this.NewSelfSynonym(); } + public override bool IsRefining { get; } public Type ConcreteBaseType(List typeArguments) { Contract.Requires(TypeArgs.Count == typeArguments.Count); diff --git a/Source/DafnyCore/AST/TypeDeclarations/NonNullTypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/NonNullTypeDecl.cs index 9a837b99815..349191aebef 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/NonNullTypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/NonNullTypeDecl.cs @@ -25,7 +25,7 @@ private NonNullTypeDecl(ClassLikeDecl cl, List tps) } private NonNullTypeDecl(ClassLikeDecl cl, List tps, BoundVar id) - : base(cl.Origin, cl.NameNode, new TypeParameter.TypeParameterCharacteristics(), tps, cl.EnclosingModuleDefinition, id, + : base(cl.Origin, cl.NameNode, new TypeParameterCharacteristics(), tps, cl.EnclosingModuleDefinition, id, new BinaryExpr(cl.Origin, BinaryExpr.Opcode.Neq, new IdentifierExpr(cl.Origin, id), new LiteralExpr(cl.Origin)), SubsetTypeDecl.WKind.Special, null, SystemModuleManager.AxiomAttribute()) { Contract.Requires(cl != null); diff --git a/Source/DafnyCore/AST/TypeDeclarations/SubsetTypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/SubsetTypeDecl.cs index 78cf075efdc..c1201fe70b3 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/SubsetTypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/SubsetTypeDecl.cs @@ -26,7 +26,7 @@ bool RedirectingTypeDecl.ConstraintIsCompilable { } } - public SubsetTypeDecl(IOrigin origin, Name name, TypeParameter.TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, + public SubsetTypeDecl(IOrigin origin, Name name, TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, BoundVar id, Expression constraint, WKind witnessKind, Expression witness, Attributes attributes) : base(origin, name, characteristics, typeArgs, module, id.Type, attributes) { diff --git a/Source/DafnyCore/AST/TypeDeclarations/TopLevelDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/TopLevelDecl.cs index ba2a5551e47..e19d2b62450 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/TopLevelDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/TopLevelDecl.cs @@ -8,6 +8,7 @@ namespace Microsoft.Dafny; public abstract class TopLevelDecl : Declaration, TypeParameter.ParentType, ISymbol { public abstract string WhatKind { get; } public string WhatKindAndName => $"{WhatKind} '{Name}'"; + [BackEdge] public ModuleDefinition EnclosingModuleDefinition; public readonly List TypeArgs; [ContractInvariantMethod] @@ -20,12 +21,12 @@ protected TopLevelDecl(Cloner cloner, TopLevelDecl original, ModuleDefinition pa EnclosingModuleDefinition = parent; } - protected TopLevelDecl(IOrigin origin, Name name, ModuleDefinition enclosingModule, List typeArgs, Attributes attributes, bool isRefining) - : base(origin, name, attributes, isRefining) { + [SyntaxConstructor] + protected TopLevelDecl(IOrigin origin, Name nameNode, ModuleDefinition enclosingModuleDefinition, List typeArgs, Attributes attributes) + : base(origin, nameNode, attributes) { Contract.Requires(origin != null); - Contract.Requires(name != null); Contract.Requires(cce.NonNullElements(typeArgs)); - EnclosingModuleDefinition = enclosingModule; + EnclosingModuleDefinition = enclosingModuleDefinition; TypeArgs = typeArgs; } diff --git a/Source/DafnyCore/AST/TypeDeclarations/TopLevelDeclWithMembers.cs b/Source/DafnyCore/AST/TypeDeclarations/TopLevelDeclWithMembers.cs index e6d990a886b..9adf38f3416 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/TopLevelDeclWithMembers.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/TopLevelDeclWithMembers.cs @@ -8,6 +8,7 @@ namespace Microsoft.Dafny; public abstract class TopLevelDeclWithMembers : TopLevelDecl, IHasSymbolChildren { + public override bool IsRefining { get; } public readonly List Members; // TODO remove this and instead clone the AST after parsing. @@ -15,7 +16,7 @@ public abstract class TopLevelDeclWithMembers : TopLevelDecl, IHasSymbolChildren // The following fields keep track of parent traits public readonly List InheritedMembers = []; // these are instance members declared in parent traits - public readonly List ParentTraits; // these are the types that are parsed after the keyword 'extends'; note, for a successfully resolved program, these are UserDefinedType's where .ResolvedClass is NonNullTypeDecl + public readonly List Traits; // these are the types that are parsed after the keyword 'extends'; note, for a successfully resolved program, these are UserDefinedType's where .ResolvedClass is NonNullTypeDecl public readonly Dictionary ParentFormalTypeParametersToActuals = new Dictionary(); // maps parent traits' type parameters to actuals /// @@ -87,16 +88,16 @@ public void Extend(TraitDecl parent, InheritanceInformationClass parentInfo, Dic } } - protected TopLevelDeclWithMembers(IOrigin origin, Name name, ModuleDefinition module, + [SyntaxConstructor] + protected TopLevelDeclWithMembers(IOrigin origin, Name nameNode, ModuleDefinition enclosingModuleDefinition, List typeArgs, List members, Attributes attributes, - bool isRefining, List/*?*/ traits = null) - : base(origin, name, module, typeArgs, attributes, isRefining) { + List/*?*/ traits = null) + : base(origin, nameNode, enclosingModuleDefinition, typeArgs, attributes) { Contract.Requires(origin != null); - Contract.Requires(name != null); Contract.Requires(cce.NonNullElements(typeArgs)); Contract.Requires(cce.NonNullElements(members)); Members = members; - ParentTraits = traits ?? []; + Traits = traits ?? []; SetMembersBeforeResolution(); } @@ -111,7 +112,7 @@ public List RawTraitsWithArgument(List typeArgs) { var subst = TypeParameter.SubstitutionMap(TypeArgs, typeArgs); var isReferenceType = this is ClassLikeDecl { IsReferenceTypeDecl: true }; var results = new List(); - foreach (var traitType in ParentTraits) { + foreach (var traitType in Traits) { var ty = (UserDefinedType)traitType.Subst(subst); Contract.Assert(isReferenceType || !ty.IsRefType); results.Add(UserDefinedType.CreateNullableTypeIfReferenceType(ty)); @@ -138,9 +139,9 @@ public static List CommonTraits(TopLevelDeclWithMembers a, TopL return types; } - public override IEnumerable Children => ParentTraits.Concat(Members); + public override IEnumerable Children => Traits.Concat(Members); - public override IEnumerable PreResolveChildren => ParentTraits.Concat(MembersBeforeResolution); + public override IEnumerable PreResolveChildren => Traits.Concat(MembersBeforeResolution); /// /// Returns the set of transitive parent traits (not including "this" itself). @@ -157,7 +158,7 @@ public ISet TraitAncestors() { /// private void AddTraitAncestors(ISet s) { Contract.Requires(s != null); - foreach (var parent in ParentTraits) { + foreach (var parent in Traits) { var udt = (UserDefinedType)parent; // in a successfully resolved program, we expect all .ParentTraits to be a UserDefinedType TraitDecl tr; if (udt.ResolvedClass is NonNullTypeDecl nntd) { @@ -175,7 +176,7 @@ private void AddTraitAncestors(ISet s) { public abstract bool AcceptThis { get; } public override bool IsEssentiallyEmpty() { - if (Members.Count != 0 || ParentTraits.Count != 0) { + if (Members.Count != 0 || Traits.Count != 0) { return false; } return base.IsEssentiallyEmpty(); diff --git a/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDecl.cs index 88fd0bf80b0..e833fa6b286 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDecl.cs @@ -6,7 +6,7 @@ namespace Microsoft.Dafny; public class TypeSynonymDecl : TypeSynonymDeclBase, RevealableTypeDecl { public override string WhatKind => "type synonym"; - public TypeSynonymDecl(IOrigin origin, Name name, TypeParameter.TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) + public TypeSynonymDecl(IOrigin origin, Name name, TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) : base(origin, name, characteristics, typeArgs, module, rhs, attributes) { this.NewSelfSynonym(); } @@ -20,7 +20,7 @@ public override string GetDescription(DafnyOptions options) { public class InternalTypeSynonymDecl : TypeSynonymDeclBase { public override string WhatKind { get { return "export-provided type"; } } - public InternalTypeSynonymDecl(IOrigin origin, Name name, TypeParameter.TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) + public InternalTypeSynonymDecl(IOrigin origin, Name name, TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) : base(origin, name, characteristics, typeArgs, module, rhs, attributes) { } diff --git a/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs b/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs index d9cb6a7c043..1df053cd9f4 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/TypeSynonymDeclBase.cs @@ -7,14 +7,14 @@ namespace Microsoft.Dafny; public abstract class TypeSynonymDeclBase : TopLevelDecl, RedirectingTypeDecl, IHasDocstring { - public TypeParameter.TypeParameterCharacteristics Characteristics; // the resolver may change the .EqualitySupport component of this value from Unspecified to InferredRequired (for some signatures that may immediately imply that equality support is required) + public TypeParameterCharacteristics Characteristics; // the resolver may change the .EqualitySupport component of this value from Unspecified to InferredRequired (for some signatures that may immediately imply that equality support is required) public bool SupportsEquality { get { return Characteristics.EqualitySupport != TypeParameter.EqualitySupportValue.Unspecified; } } public readonly Type Rhs; - protected TypeSynonymDeclBase(IOrigin origin, Name name, TypeParameter.TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) - : base(origin, name, module, typeArgs, attributes, false) { + protected TypeSynonymDeclBase(IOrigin origin, Name name, TypeParameterCharacteristics characteristics, List typeArgs, ModuleDefinition module, Type rhs, Attributes attributes) + : base(origin, name, module, typeArgs, attributes) { Contract.Requires(origin != null); Contract.Requires(name != null); Contract.Requires(typeArgs != null); diff --git a/Source/DafnyCore/AST/TypeDeclarations/ValuetypeDecl.cs b/Source/DafnyCore/AST/TypeDeclarations/ValuetypeDecl.cs index 3033b550fa0..82119948c8e 100644 --- a/Source/DafnyCore/AST/TypeDeclarations/ValuetypeDecl.cs +++ b/Source/DafnyCore/AST/TypeDeclarations/ValuetypeDecl.cs @@ -16,7 +16,7 @@ public class ValuetypeDecl : TopLevelDeclWithMembers { public override bool AcceptThis => true; public ValuetypeDecl(string name, ModuleDefinition module, Func typeTester, Func, Type> typeCreator /*?*/) - : base(SourceOrigin.NoToken, new Name(name), module, [], [], null, false, null) { + : base(SourceOrigin.NoToken, new Name(name), module, [], [], null, null) { Contract.Requires(name != null); Contract.Requires(module != null); Contract.Requires(typeTester != null); @@ -45,7 +45,7 @@ public ValuetypeDecl(string name, ModuleDefinition module, List typeParameters, List members, Attributes attributes, Func typeTester, Func, Type> /*?*/ typeCreator) - : base(SourceOrigin.NoToken, new Name(name), module, typeParameters, members, attributes, false) { + : base(SourceOrigin.NoToken, new Name(name), module, typeParameters, members, attributes) { this.typeTester = typeTester; this.typeCreator = typeCreator; } diff --git a/Source/DafnyCore/AST/Types/TypeParameter.cs b/Source/DafnyCore/AST/Types/TypeParameter.cs index 0e7730275bb..17804e68adc 100644 --- a/Source/DafnyCore/AST/Types/TypeParameter.cs +++ b/Source/DafnyCore/AST/Types/TypeParameter.cs @@ -125,43 +125,7 @@ public static List Variances(List typeParameters, boo } public enum EqualitySupportValue { Required, InferredRequired, Unspecified } - public struct TypeParameterCharacteristics { - public SourceOrigin SourceOrigin = null; - public EqualitySupportValue EqualitySupport; // the resolver may change this value from Unspecified to InferredRequired (for some signatures that may immediately imply that equality support is required) - public Type.AutoInitInfo AutoInit; - public bool HasCompiledValue => AutoInit == Type.AutoInitInfo.CompilableValue; - public bool IsNonempty => AutoInit != Type.AutoInitInfo.MaybeEmpty; - public bool ContainsNoReferenceTypes; - public TypeParameterCharacteristics(bool dummy) { - EqualitySupport = EqualitySupportValue.Unspecified; - AutoInit = Type.AutoInitInfo.MaybeEmpty; - ContainsNoReferenceTypes = false; - } - public TypeParameterCharacteristics(EqualitySupportValue eqSupport, Type.AutoInitInfo autoInit, bool containsNoReferenceTypes) { - EqualitySupport = eqSupport; - AutoInit = autoInit; - ContainsNoReferenceTypes = containsNoReferenceTypes; - } - public override string ToString() { - string result = ""; - if (EqualitySupport == EqualitySupportValue.Required) { - result += ",=="; - } - if (HasCompiledValue) { - result += ",0"; - } - if (AutoInit == Type.AutoInitInfo.Nonempty) { - result += ",00"; - } - if (ContainsNoReferenceTypes) { - result += ",!new"; - } - if (result.Length != 0) { - result = "(" + result.Substring(1) + ")"; - } - return result; - } - } + public TypeParameterCharacteristics Characteristics; public bool SupportsEquality { get { return Characteristics.EqualitySupport != EqualitySupportValue.Unspecified; } @@ -186,18 +150,19 @@ public IEnumerable TypeBoundHeads { } } - public TypeParameter(IOrigin origin, Name name, TPVarianceSyntax varianceS, TypeParameterCharacteristics characteristics, - List typeBounds) - : base(origin, name, null, [], null, false) { + [SyntaxConstructor] + public TypeParameter(IOrigin origin, Name nameNode, TPVarianceSyntax varianceSyntax, + TypeParameterCharacteristics characteristics, + List typeBounds, Attributes attributes = null) + : base(origin, nameNode, null, [], attributes) { Contract.Requires(origin != null); - Contract.Requires(name != null); Characteristics = characteristics; - VarianceSyntax = varianceS; + VarianceSyntax = varianceSyntax; TypeBounds = typeBounds; } - public TypeParameter(IOrigin origin, Name name, TPVarianceSyntax varianceS) - : this(origin, name, varianceS, new TypeParameterCharacteristics(false), []) { + public TypeParameter(IOrigin origin, Name name, TPVarianceSyntax varianceSyntax) + : this(origin, name, varianceSyntax, new TypeParameterCharacteristics(false), []) { Contract.Requires(origin != null); Contract.Requires(name != null); } diff --git a/Source/DafnyCore/AST/Types/TypeParameterCharacteristics.cs b/Source/DafnyCore/AST/Types/TypeParameterCharacteristics.cs new file mode 100644 index 00000000000..a98bed549a0 --- /dev/null +++ b/Source/DafnyCore/AST/Types/TypeParameterCharacteristics.cs @@ -0,0 +1,39 @@ +namespace Microsoft.Dafny; + +public struct TypeParameterCharacteristics { + public SourceOrigin SourceOrigin = null; + public TypeParameter.EqualitySupportValue EqualitySupport; // the resolver may change this value from Unspecified to InferredRequired (for some signatures that may immediately imply that equality support is required) + public Type.AutoInitInfo AutoInit; + public bool HasCompiledValue => AutoInit == Type.AutoInitInfo.CompilableValue; + public bool IsNonempty => AutoInit != Type.AutoInitInfo.MaybeEmpty; + public bool ContainsNoReferenceTypes; + public TypeParameterCharacteristics(bool dummy) { + EqualitySupport = TypeParameter.EqualitySupportValue.Unspecified; + AutoInit = Type.AutoInitInfo.MaybeEmpty; + ContainsNoReferenceTypes = false; + } + public TypeParameterCharacteristics(TypeParameter.EqualitySupportValue equalitySupport, Type.AutoInitInfo autoInit, bool containsNoReferenceTypes) { + EqualitySupport = equalitySupport; + AutoInit = autoInit; + ContainsNoReferenceTypes = containsNoReferenceTypes; + } + public override string ToString() { + string result = ""; + if (EqualitySupport == TypeParameter.EqualitySupportValue.Required) { + result += ",=="; + } + if (HasCompiledValue) { + result += ",0"; + } + if (AutoInit == Type.AutoInitInfo.Nonempty) { + result += ",00"; + } + if (ContainsNoReferenceTypes) { + result += ",!new"; + } + if (result.Length != 0) { + result = "(" + result.Substring(1) + ")"; + } + return result; + } +} \ No newline at end of file diff --git a/Source/DafnyCore/AST/Types/Types.cs b/Source/DafnyCore/AST/Types/Types.cs index 37041e01890..24f4f9dff1e 100644 --- a/Source/DafnyCore/AST/Types/Types.cs +++ b/Source/DafnyCore/AST/Types/Types.cs @@ -361,7 +361,7 @@ public bool IsNumericBased(NumericPersuasion p) { /// Returns true if the type has two representations at run time, the ordinary representation and a /// "fat pointer" representation (which is a boxing of the ordinary representation, plus a vtable pointer). /// - public bool HasFatPointer => NormalizeExpand() is UserDefinedType { ResolvedClass: NewtypeDecl { ParentTraits: { Count: > 0 } } }; + public bool HasFatPointer => NormalizeExpand() is UserDefinedType { ResolvedClass: NewtypeDecl { Traits: { Count: > 0 } } }; /// /// This property returns true if the type is known to be nonempty. @@ -401,7 +401,7 @@ public AutoInitInfo GetAutoInit(List/*?*/ coDatatypesBeingVisit var t = NormalizeExpandKeepConstraints(); Contract.Assume(t is NonProxyType); // precondition - AutoInitInfo CharacteristicToAutoInitInfo(TypeParameter.TypeParameterCharacteristics c) { + AutoInitInfo CharacteristicToAutoInitInfo(TypeParameterCharacteristics c) { if (c.HasCompiledValue) { return AutoInitInfo.CompilableValue; } else if (c.IsNonempty) { diff --git a/Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs b/Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs index fc46c7f8bd9..10b6c2bf0bd 100644 --- a/Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs +++ b/Source/DafnyCore/Backends/CSharp/CsharpCodeGenerator.cs @@ -1269,7 +1269,7 @@ protected override IClassWriter DeclareNewtype(NewtypeDecl nt, ConcreteSyntaxTre EmitTypeDescriptorMethod(nt, w); GenerateIsMethod(nt, cw.StaticMemberWriter); - if (nt.ParentTraits.Count != 0) { + if (nt.Traits.Count != 0) { DeclareBoxedNewtype(nt, cw.InstanceMemberWriter); } diff --git a/Source/DafnyCore/Backends/Dafny/DafnyCodeGenerator.cs b/Source/DafnyCore/Backends/Dafny/DafnyCodeGenerator.cs index fbb1ea3c1ac..9f33fd0862f 100644 --- a/Source/DafnyCore/Backends/Dafny/DafnyCodeGenerator.cs +++ b/Source/DafnyCore/Backends/Dafny/DafnyCodeGenerator.cs @@ -252,7 +252,7 @@ protected override IClassWriter CreateTrait(string name, bool isExtern, List { + ref externVal, new HashSet { Attributes.MatchingValueOption.String }, s => throw new UnsupportedInvalidOperationException("Non-string externs for destructors")); var destructorName = externVal as string ?? defaultName; diff --git a/Source/DafnyCore/Backends/DatatypeWrapperEraser.cs b/Source/DafnyCore/Backends/DatatypeWrapperEraser.cs index f15de83f5ad..c4a4ddec601 100644 --- a/Source/DafnyCore/Backends/DatatypeWrapperEraser.cs +++ b/Source/DafnyCore/Backends/DatatypeWrapperEraser.cs @@ -168,7 +168,7 @@ private static bool FindUnwrappedCandidate(DafnyOptions options, DatatypeDecl da if (datatypeDecl is IndDatatypeDecl && !datatypeDecl.IsExtern(options, out _, out _) && !datatypeDecl.Members.Any(member => member is Field { IsGhost: false }) && - datatypeDecl.ParentTraits.Count == 0) { + datatypeDecl.Traits.Count == 0) { var nonGhostConstructors = datatypeDecl.Ctors.Where(ctor => !ctor.IsGhost).ToList(); if (nonGhostConstructors.Count == 1) { // there is exactly one non-ghost constructor diff --git a/Source/DafnyCore/Backends/GoLang/GoCodeGenerator.cs b/Source/DafnyCore/Backends/GoLang/GoCodeGenerator.cs index ca15e2061b9..2f097ae5d92 100644 --- a/Source/DafnyCore/Backends/GoLang/GoCodeGenerator.cs +++ b/Source/DafnyCore/Backends/GoLang/GoCodeGenerator.cs @@ -390,7 +390,7 @@ private GoCodeGenerator.ClassWriter CreateClass(TopLevelDecl classContext, bool w.WriteLine(); CreateInitializer(classContext, name, w, out var instanceFieldInitWriter, out var traitInitWriter, out var rtdParamWriter); - var isNewtypeWithTraits = classContext is NewtypeDecl { ParentTraits: { Count: > 0 } }; + var isNewtypeWithTraits = classContext is NewtypeDecl { Traits: { Count: > 0 } }; var rtdCount = 0; if (typeParameters != null) { @@ -528,7 +528,7 @@ protected void CreateInitializer(TopLevelDecl classContext, string name, Concret wr.Write("func {0}(", FormatInitializerName(name)); rtdParamWriter = wr.Fork(); var w = wr.NewNamedBlock(") *{0}", name); - var parameters = classContext is NewtypeDecl { ParentTraits: { Count: > 0 } } ? "value" : ""; + var parameters = classContext is NewtypeDecl { Traits: { Count: > 0 } } ? "value" : ""; w.WriteLine($"_this := {name}{{{parameters}}}"); w.WriteLine(); @@ -1076,7 +1076,7 @@ string StructOfCtor(DatatypeCtor ctor) { wDefault.WriteLine($"return {TypeName_Companion(dt, wr, dt.Origin)}.Default({typeDescriptorUses}{sep}{arguments});"); } - EmitParentTraits(dt.Origin, name, false, dt.ParentTraits, wr); + EmitParentTraits(dt.Origin, name, false, dt.Traits, wr); return new ClassWriter(this, dt, false, name, dt.IsExtern(Options, out _, out _), null, wr, wr, wr, wr, staticFieldWriter, staticFieldInitWriter); @@ -1121,7 +1121,7 @@ protected override IClassWriter DeclareNewtype(NewtypeDecl nt, ConcreteSyntaxTre GenerateIsMethod(nt, wr); - if (nt.ParentTraits.Count != 0) { + if (nt.Traits.Count != 0) { cw.InstanceFieldWriter.WriteLine($"_value {TypeName(udt, cw.InstanceFieldWriter, nt.Origin)}"); } diff --git a/Source/DafnyCore/Backends/Java/JavaCodeGenerator.cs b/Source/DafnyCore/Backends/Java/JavaCodeGenerator.cs index 4bbab1a1226..fc6920fb520 100644 --- a/Source/DafnyCore/Backends/Java/JavaCodeGenerator.cs +++ b/Source/DafnyCore/Backends/Java/JavaCodeGenerator.cs @@ -3630,7 +3630,7 @@ protected override IClassWriter DeclareNewtype(NewtypeDecl nt, ConcreteSyntaxTre GenerateIsMethod(nt, cw.StaticMemberWriter); - if (nt.ParentTraits.Count != 0) { + if (nt.Traits.Count != 0) { DeclareBoxedNewtype(nt, cw.InstanceMemberWriter); } diff --git a/Source/DafnyCore/Backends/JavaScript/JavaScriptCodeGenerator.cs b/Source/DafnyCore/Backends/JavaScript/JavaScriptCodeGenerator.cs index 9550e900a7c..4fda5e78664 100644 --- a/Source/DafnyCore/Backends/JavaScript/JavaScriptCodeGenerator.cs +++ b/Source/DafnyCore/Backends/JavaScript/JavaScriptCodeGenerator.cs @@ -99,7 +99,7 @@ protected override IClassWriter CreateClass(string moduleName, bool isExtern, st if (typeParameters != null && WriteRuntimeTypeDescriptorsFormals(typeParameters, false, w) > 0) { sep = ", "; } - if (cls is NewtypeDecl { ParentTraits: { } parentTraits } && parentTraits.Count > 0) { + if (cls is NewtypeDecl { Traits: { } parentTraits } && parentTraits.Count > 0) { w.Write($"{sep}value"); } var fieldWriter = w.NewBlock(")"); @@ -604,7 +604,7 @@ protected override IClassWriter DeclareNewtype(NewtypeDecl nt, ConcreteSyntaxTre GenerateIsMethod(nt, cw.MethodWriter); - if (nt.ParentTraits.Count != 0) { + if (nt.Traits.Count != 0) { // in constructor: // this._value = value; cw.FieldWriter.WriteLine("this._value = value;"); diff --git a/Source/DafnyCore/Backends/Python/PythonCodeGenerator.cs b/Source/DafnyCore/Backends/Python/PythonCodeGenerator.cs index b34c109afd9..d1e48319e12 100644 --- a/Source/DafnyCore/Backends/Python/PythonCodeGenerator.cs +++ b/Source/DafnyCore/Backends/Python/PythonCodeGenerator.cs @@ -243,7 +243,7 @@ protected override IClassWriter CreateClass(string moduleName, bool isExtern, st var relevantTypeParameters = typeParameters.Where(NeedsTypeDescriptor).ToList(); var args = relevantTypeParameters.Comma(tp => tp.GetCompileName(Options)); if (!string.IsNullOrEmpty(args)) { args = $", {args}"; } - var isNewtypeWithTraits = cls is NewtypeDecl { ParentTraits: { Count: > 0 } }; + var isNewtypeWithTraits = cls is NewtypeDecl { Traits: { Count: > 0 } }; if (isNewtypeWithTraits) { args += ", value"; } @@ -475,7 +475,7 @@ protected IClassWriter DeclareType(TopLevelDecl d, SubsetTypeDecl.WKind witnessK GenerateIsMethod((RedirectingTypeDecl)d, w); - if (d is NewtypeDecl newtypeDecl && newtypeDecl.ParentTraits.Count != 0) { + if (d is NewtypeDecl newtypeDecl && newtypeDecl.Traits.Count != 0) { // in constructor: // self._value = value cw.ConstructorWriter.WriteLine("self._value = value"); diff --git a/Source/DafnyCore/Dafny.atg b/Source/DafnyCore/Dafny.atg index 2f45f035fd3..e1012d94661 100644 --- a/Source/DafnyCore/Dafny.atg +++ b/Source/DafnyCore/Dafny.atg @@ -817,7 +817,7 @@ SynonymTypeName = Name . // The following includes Opaque type definitions SynonymTypeDecl = (. Token bvId; - var characteristics = new TypeParameter.TypeParameterCharacteristics(false); + var characteristics = new TypeParameterCharacteristics(false); var typeArgs = new List(); td = null; Type ty = null; @@ -1081,7 +1081,7 @@ GenericParameters<.List typeParameters, bool allowVariance.> OneTypeParameter<.List typeParameters, bool allowVariance.> = (. var variance = TypeParameter.TPVarianceSyntax.NonVariant_Strict; // assignment is to please compiler - var characteristics = new TypeParameter.TypeParameterCharacteristics(false); + var characteristics = new TypeParameterCharacteristics(false); Name name; Type typeBound; var typeBounds = new List(); @@ -1114,7 +1114,7 @@ Variance . /*------------------------------------------------------------------------*/ -TypeParameterCharacteristics +TypeParameterCharacteristics = "(" (. var startToken = t; .) TPCharOption { "," @@ -1123,7 +1123,7 @@ TypeParameterCharacteristics +TPCharOption = ( "==" (. characteristics.EqualitySupport = TypeParameter.EqualitySupportValue.Required; .) | digits (. if (t.val == "0") { characteristics.AutoInit = Microsoft.Dafny.Type.AutoInitInfo.CompilableValue; diff --git a/Source/DafnyCore/Generic/Name.cs b/Source/DafnyCore/Generic/Name.cs index e3ee7bf4573..3112a1009df 100644 --- a/Source/DafnyCore/Generic/Name.cs +++ b/Source/DafnyCore/Generic/Name.cs @@ -28,7 +28,7 @@ public Name(Cloner cloner, Name original) : base(cloner, original) { Value = original.Value; } - public Name(IOrigin range, string value) : base(range) { + public Name(IOrigin origin, string value) : base(origin) { this.Value = value; } diff --git a/Source/DafnyCore/Generic/Node.cs b/Source/DafnyCore/Generic/Node.cs index 895cc88e2df..5dfb71d7957 100644 --- a/Source/DafnyCore/Generic/Node.cs +++ b/Source/DafnyCore/Generic/Node.cs @@ -8,6 +8,26 @@ namespace Microsoft.Dafny; +/// +/// Indicates that this constructor is used to define an AST type corresponding to the syntax of Dafny +/// +/// These constructors are invoked by the Dafny parser defined in Dafny.atg +/// and by the Dafny deserializer. +/// +/// The attribute is used by DeserializerGenerator. +/// +[AttributeUsage(AttributeTargets.Constructor)] +public class SyntaxConstructorAttribute : Attribute { } + +/// +/// Used by the command '--generate-parsed-ast'. This attribute will cause the field to be ignored. +/// Some constructors used during parsing also have a parameter whose value that points to the container of the object that is +/// to be constructed. This parameters should not end up in the generated 'parsed AST', so their related fields +/// are annotated with this attribute. +/// +[AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Field)] +public class BackEdge : Attribute { } + public abstract class Node : INode { private static readonly Regex StartDocstringExtractor = new Regex($@"/\*\*(?{TriviaFormatterHelper.MultilineCommentContent})\*/"); diff --git a/Source/DafnyCore/Generic/RangeNode.cs b/Source/DafnyCore/Generic/RangeNode.cs index 64562a9f8ac..f5984bd05e2 100644 --- a/Source/DafnyCore/Generic/RangeNode.cs +++ b/Source/DafnyCore/Generic/RangeNode.cs @@ -9,6 +9,7 @@ protected RangeNode(Cloner cloner, RangeNode original) { origin = cloner.Origin(original.Origin); } + [SyntaxConstructor] protected RangeNode(IOrigin origin) { this.origin = origin; } diff --git a/Source/DafnyCore/Options/CommonOptionBag.cs b/Source/DafnyCore/Options/CommonOptionBag.cs index 99371b3a513..f1bd2f0161b 100644 --- a/Source/DafnyCore/Options/CommonOptionBag.cs +++ b/Source/DafnyCore/Options/CommonOptionBag.cs @@ -12,6 +12,15 @@ namespace Microsoft.Dafny; public class CommonOptionBag { + public enum InputTypeEnum { + Source, + Binary + } + + public static readonly Option InputType = new("--input-format", () => InputTypeEnum.Source) { + IsHidden = true + }; + public static void EnsureStaticConstructorHasRun() { } public enum ProgressLevel { None, Symbol, Batch } @@ -660,6 +669,7 @@ void ParsePrintMode(Option option, Boogie.CommandLineParseState ps, OptionRegistry.RegisterOption(ExecutionCoverageReport, OptionScope.Cli); OptionRegistry.RegisterOption(ExtractCounterexample, OptionScope.Cli); OptionRegistry.RegisterOption(ShowProofObligationExpressions, OptionScope.Cli); + OptionRegistry.RegisterOption(InputType, OptionScope.Cli); } } diff --git a/Source/DafnyCore/Options/DafnyCommands.cs b/Source/DafnyCore/Options/DafnyCommands.cs index 3f8c281c9ce..93ca8d17f95 100644 --- a/Source/DafnyCore/Options/DafnyCommands.cs +++ b/Source/DafnyCore/Options/DafnyCommands.cs @@ -79,7 +79,8 @@ static DafnyCommands() { DeveloperOptionBag.BoogiePrint, Printer.PrintMode, CommonOptionBag.AllowWarnings, - CommonOptionBag.WarnAsErrors + CommonOptionBag.WarnAsErrors, + CommonOptionBag.InputType }); public static readonly IReadOnlyList public IEnumerable AllParentTraits(TopLevelDeclWithMembers decl) { - foreach (var parentType in decl.ParentTraits) { + foreach (var parentType in decl.Traits) { yield return parentType; } if (DPreType.IsReferenceTypeDecl(decl)) { diff --git a/Source/DafnyCore/Resolver/PreType/PreTypeResolve.cs b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.cs index 923652fffa1..51fb01d41c9 100644 --- a/Source/DafnyCore/Resolver/PreType/PreTypeResolve.cs +++ b/Source/DafnyCore/Resolver/PreType/PreTypeResolve.cs @@ -321,7 +321,7 @@ public static bool HasTraitSupertypes(DPreType dp) { * return dp.Decl is TopLevelDeclWithMembers md && md.ParentTraits.Count != 0; * For now, every reference type except "object" has trait supertypes. */ - if (dp.Decl is TopLevelDeclWithMembers md && md.ParentTraits.Count != 0) { + if (dp.Decl is TopLevelDeclWithMembers md && md.Traits.Count != 0) { // this type has explicitly declared parent traits return true; } diff --git a/Source/DafnyCore/Resolver/TypeCharacteristicChecker.cs b/Source/DafnyCore/Resolver/TypeCharacteristicChecker.cs index cf5b4bd0a9a..b0539b7d326 100644 --- a/Source/DafnyCore/Resolver/TypeCharacteristicChecker.cs +++ b/Source/DafnyCore/Resolver/TypeCharacteristicChecker.cs @@ -225,7 +225,7 @@ private static void Check(List declarations, bool isAnExport, Erro visitor.Visit(iter.Body, false); } } else if (d is ClassLikeDecl cl) { - foreach (var parentTrait in cl.ParentTraits) { + foreach (var parentTrait in cl.Traits) { visitor.VisitType(cl.Origin, parentTrait, false); } } else if (d is DatatypeDecl dt) { diff --git a/Source/DafnyCore/Rewriters/RefinementTransformer.cs b/Source/DafnyCore/Rewriters/RefinementTransformer.cs index 537345ee4c1..24c0e4cea80 100644 --- a/Source/DafnyCore/Rewriters/RefinementTransformer.cs +++ b/Source/DafnyCore/Rewriters/RefinementTransformer.cs @@ -632,7 +632,7 @@ IteratorDecl MergeIterator(IteratorDecl nw, IteratorDecl prev) { TopLevelDeclWithMembers MergeClass(TopLevelDeclWithMembers nw, TopLevelDeclWithMembers prev) { CheckAgreement_TypeParameters(nw.Origin, prev.TypeArgs, nw.TypeArgs, nw.Name, nw.WhatKind); - prev.ParentTraits.ForEach(item => nw.ParentTraits.Add(refinementCloner.CloneType(item))); + prev.Traits.ForEach(item => nw.Traits.Add(refinementCloner.CloneType(item))); nw.Attributes = refinementCloner.MergeAttributes(prev.Attributes, nw.Attributes); // Create a simple name-to-member dictionary. Ignore any duplicates at this time. diff --git a/Source/DafnyCore/Verifier/BoogieGenerator.Methods.cs b/Source/DafnyCore/Verifier/BoogieGenerator.Methods.cs index dfafd2dd3af..afb057933eb 100644 --- a/Source/DafnyCore/Verifier/BoogieGenerator.Methods.cs +++ b/Source/DafnyCore/Verifier/BoogieGenerator.Methods.cs @@ -465,7 +465,7 @@ private void AddImplementsAxioms(ClassDecl c) { //this adds: axiom implements$J(class.C, typeInstantiations); var vars = MkTyParamBinders(GetTypeParams(c), out var tyexprs); - foreach (var parent in c.ParentTraits) { + foreach (var parent in c.Traits) { var trait = ((UserDefinedType)parent).AsParentTraitDecl(); Contract.Assert(trait != null); var arg = ClassTyCon(c, tyexprs); diff --git a/Source/DafnyCore/Verifier/BoogieGenerator.cs b/Source/DafnyCore/Verifier/BoogieGenerator.cs index 0f98bfff7a8..b693296d829 100644 --- a/Source/DafnyCore/Verifier/BoogieGenerator.cs +++ b/Source/DafnyCore/Verifier/BoogieGenerator.cs @@ -1087,7 +1087,7 @@ private void CreateRevealableConstant(Function f) { private void AddTraitParentAxioms() { foreach (ModuleDefinition m in program.RawModules()) { foreach (var c in m.TopLevelDecls.OfType().Where(RevealedInScope)) { - foreach (var parentTypeInExtendsClause in c.ParentTraits) { + foreach (var parentTypeInExtendsClause in c.Traits) { var childType = UserDefinedType.FromTopLevelDecl(c.Origin, c); var parentType = (UserDefinedType)parentTypeInExtendsClause; if (parentType.IsRefType) { @@ -4829,7 +4829,7 @@ List MkTyParamFormals(List args, bool includeWhereClaus return vars; } - public Bpl.Expr/*?*/ GetTyWhereClause(Bpl.Expr expr, TypeParameter.TypeParameterCharacteristics characteristics) { + public Bpl.Expr/*?*/ GetTyWhereClause(Bpl.Expr expr, TypeParameterCharacteristics characteristics) { Contract.Requires(expr != null); if (characteristics.ContainsNoReferenceTypes) { return FunctionCall(expr.tok, "$AlwaysAllocated", Bpl.Type.Bool, expr); diff --git a/Source/DafnyDriver/Commands/BoogieExtractor.cs b/Source/DafnyDriver/Commands/BoogieExtractor.cs index 87a9dfc076d..da6fe82c0c4 100644 --- a/Source/DafnyDriver/Commands/BoogieExtractor.cs +++ b/Source/DafnyDriver/Commands/BoogieExtractor.cs @@ -258,7 +258,7 @@ private Boogie.Type ExtractType(Type type) { } } - private string? GetExtractName(Attributes attributes) { + private string? GetExtractName(Attributes? attributes) { if (Attributes.Find(attributes, NameAttribute) is { } extractNameAttribute) { if (extractNameAttribute.Args.Count == 1 && extractNameAttribute.Args[0] is StringLiteralExpr { Value: string extractName }) { return extractName; diff --git a/Source/DafnyDriver/DafnyDoc.cs b/Source/DafnyDriver/DafnyDoc.cs index 27a38716fa2..58876d0a536 100644 --- a/Source/DafnyDriver/DafnyDoc.cs +++ b/Source/DafnyDriver/DafnyDoc.cs @@ -610,8 +610,8 @@ public Info TypeInfo(bool register, TopLevelDecl t, ModuleDefinition module, Inf decl.Append(typeparams); if (t is ClassLikeDecl cd) { // Class, Trait, Iterator - if (cd.ParentTraits.Count > 0) { - var extends = String.Join(", ", cd.ParentTraits.Select(t => TypeLink(t))); + if (cd.Traits.Count > 0) { + var extends = String.Join(", ", cd.Traits.Select(t => TypeLink(t))); if (!String.IsNullOrEmpty(extends)) { decl.Append(" ").Append("extends").Append(" ").Append(extends); } diff --git a/Source/DafnyLanguageServer/Language/Symbols/SymbolTableFactory.cs b/Source/DafnyLanguageServer/Language/Symbols/SymbolTableFactory.cs index 3e7cade4516..ddc014543fb 100644 --- a/Source/DafnyLanguageServer/Language/Symbols/SymbolTableFactory.cs +++ b/Source/DafnyLanguageServer/Language/Symbols/SymbolTableFactory.cs @@ -112,7 +112,7 @@ public override void Visit(DatatypeDecl datatypeDeclaration) { private void VisitTopLevelDeclarationWithMembers(TopLevelDeclWithMembers declaration, System.Action visit) { cancellationToken.ThrowIfCancellationRequested(); - foreach (var parentTrait in declaration.ParentTraits) { + foreach (var parentTrait in declaration.Traits) { RegisterTypeDesignator(currentScope, parentTrait); } ProcessNestedScope(declaration, declaration.Origin, visit); diff --git a/Source/DafnyLanguageServer/Workspace/ProjectManager.cs b/Source/DafnyLanguageServer/Workspace/ProjectManager.cs index eb2646c140c..81d49463049 100644 --- a/Source/DafnyLanguageServer/Workspace/ProjectManager.cs +++ b/Source/DafnyLanguageServer/Workspace/ProjectManager.cs @@ -315,7 +315,7 @@ public async Task VerifyEverythingAsync(Uri? uri) { int GetPriorityAttribute(ISymbol symbol) { if (symbol is IAttributeBearingDeclaration hasAttributes && hasAttributes.HasUserAttribute("priority", out var attribute) && - attribute.Args.Count >= 1 && attribute.Args[0] is LiteralExpr { Value: BigInteger priority }) { + attribute!.Args.Count >= 1 && attribute.Args[0] is LiteralExpr { Value: BigInteger priority }) { return (int)priority; } return 0; diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-cs.doo index 329337064f2bc1aa405fdb38770288494883fd0a..cab8208ab7c9753e47331898d65d11dabfecb018 100644 GIT binary patch delta 1489 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 diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-go.doo index b9f0c05f7ad759a0a2926a10a47e502f26494134..8f91275a2a65afe4bf5d220719cc9e92b236a2b4 100644 GIT binary patch delta 1495 zcmV;|1t|Kb44(`QP)h>@6aWAK2mq{LRFMrif0dF_6YuMnvQx(?dYvH$oEe5v&XE$H z|DY%pe);+`oQ|)#TTV8Dx@hq~_W8N5{#hU9$VD&XtCt5*;v9v^V9L1%|hoVzZv9qS1n ze*?&|h({w$Iun!TjpK4(-4HU@HxsIIWfSf>)YT$R@O1UJ))CREXZDvg{ipG`q4 zZ~zG|(VKwmPw9?+xr>mUj4|SBZ_#Z`z65lB0{M$|uTCcjjKXrJgtI#;wYi#)M2KNVgmeXc)T307d%z&>&_Fk6=)?WzJ$+<_~^7>>? zL1nToc@6aWAK2mq{LR9ejmJhH_De*gd% z5C8xN0001Ra&KpHVQs}%-*3|}5Pt7paqyH#CBPdBZDGI$Q#U}{7>|>i+%~I89Be1* z82#U|orE}PesmyU(zMRLyYIWt=R5c5Q;@fKm2!5&Nj#ZMUcY5=N+WcxNhHvn#4OAr zgnK{C;`r`3P8pY{7_X4S<9B-Lf9mS-6eQ1Z3+FQQ-m|wX2{O(xk-#yHNPq&YwfhM` z5D_6%Ox#H1$resCNmdb_l61Co=5u!nm-^2FJkK)@0Iv@=l*JIRL@2O8GH&@hH@8ek zph@n7vsB(LJXyesv1kgbJBeb6cfvOd?!<&E98!)U4TwazBoPfA*X$L5e_)a_AGZ^m zLX7g3g%-LF?zk#hnejw`vo>G?cK|K6k}B!v=P4RtogX zG4x}Jal@PHg~GXzaV)~;Od9f2P|9D97{5o^&XoJ`DV3BZ<7Ce;W;qrChAq$OceJw# zd`O7YXKN0!U3>?U#WZ-se>Ss=-zvC^y4Ixn?=KXX7S77YLK!-j!mKCh6BexZPId%L z#~QQwl0=1-=A#&uok8DvC|iu~9*sVsY^mutz*0;wgs+^WDRS{EACtwsrFTv^P@$Kr z8&uG;6Dtn^027gM)tnwx9))em{iNcne>i^2Xw$aZAfZq#l!|geesSvEo_c^v<9jp_+4MSgnzn1pXY#al5}@!&7HaxogHr6u}yPs9&0Zb_L%D+)yC} zDiK4OK3SJ&?vn+de7gD#cu8e z#X5kK5_zi%M{=6n)JaukB@Q`f+_#&84xuaU+iaD;SWE%6#i_WdgA6kG%2lZu3KwjL zKnYQYA7iu&-aolV_4;2b{Y!0j^sogO$=kZKn#UQ6ERwT2$HL6;Dkf6#)-j|kS!!l_ zs&t-;H*ys2Y|BZVIne70MSoLF;E2#j^$VwhaRJp`g!3#=*G4$Mh?po_>mVMef43fv zJEp_~((hzcGWjDB9JkKC=LuWybduEjxY7HDhWdV<(@?dgofDhx=sLAP6ocRT`3X=< z0Rj{Q6aWAK2mq{LRFkj;87QQI00000ZDDR{W@U49E_82gY*0%90u%!j000080IXnC xTFnVOvc;3}1rsBrfv*7o0B~||XL4a}P)h{{000000ssO4Z~y=RnFRm<002>4w~qh- delta 1516 zcmV@6aWAK2ms7jMUf3Tf8`~mChqG?*{PE(dYu^#I75a~&XE$H zf1@ZBe);+`oQ|)&8L+3Py|M3 zsk+$M_hwz0!Bg$ghHnC_Gl=bJ2PcKMe}s+;Ct?I~wq>0xDEZxOchQ9_T-Os1hYZ~8 zI0@6aWAK2ms7jMOw`XJhIILe*gd% z5C8xN0001Ra&KpHVQs}%+iu%95PkPoO#37OUUmCcsJ7d*P1?Xsx=7OWF`%VMLRb=2 zk`kO|{qM_*R8h7rPK(_Q5X2#8=A1bk&d@JjfV{_>oU=Pl(#d4<_B~5;nxJ<}5`q3C zWpR-pJcegp5diw&oyri|&+8P=?OMn)M|8nMLb^ zlN|xmvBqq^W{I`Zd=#UqGw53nRg2Nxqtz#rEj9fHSdJOS@Qsr^M=pNmW3qU3^ezbp zD)e%FgDfpKvFZ>2FcSq=&FNX~VQnk!RaVxN&>7Sitkxh$RIZ&kW0n~`UynmdFWD*9daS?QT8=hD(l1GNM5xi)CY&{^Yd>W|x9 zH7$f2#4Y=NI!-)CoZcDKBUF3N468LVlOUW!HEs_VYb;w~9eAA9W9A9Z)Dsow^vh|c9Z7O*0*L0t+P$rNf5HAU>ip{X;{53I&4r@- zPG9X4&Qcw~%Za>Kg(Er5?wX|PvJ%IfGj&2vQ_vxFrG1~R%2$giptd*@cTJE%2H&_U zHACTw?GdOTn($+c_QCrn_o!a~mrDPoHhX%w0*vJC+*!@z0!5L?S(BqRGra6XvTq$j z%8{jErl(5hf2jl`N8!IV@hu;qw>66XrkKGAp^54jUJc^|s=El6MWn8c@O~08QOsqp z@_(ZK-FkTbm=aG&zmrkLic;~W7U@SPHeiTt6r%= z6oX&-`3F!-0Rj{N6aWAK2ms7jMOydWPyK`e001ikO8@{300000000000000000000 z0BvDzX=Y_}bS`vnZER3W0Rj{N6aWAK2ms7jMOw`XJhIIL000*d000L70000000000 S00000ll}!82B8H20001yUBw;% diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-java.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-java.doo index 8b98ba38a4ee4a625b227ba1098ca6790e6418fd..ebce54481d00c1c8a093ebf94e6f3667b26e584d 100644 GIT binary patch delta 1507 zcmZ9McQo4z6vuxgi1nx%)px9VZ6roZwN~^suUad%B1CPqHwV>3DPo3Jqr_-mNl-$g zRWV*rrKlRQ)vOt_%c}A8ywUUCy?@+$&pqG!$Gzu%68Z3a{HBH=urL4s5P5H?888%;nh#0#+mc27$Nev^bU= zje!XnP#Cxg{6djQ8#7?rOld%RKO#D_W1uP3z>0)V7hZR4On#J5yS64?e_c3!HfkC^ zwaj>GEqF#!Dxea1Gr=^sPKhS5%q@ijy?KV$l{L~let$moLy*I`AQHlgiXj(MD?4o{ zLbaF&gF9d~X3`nU-aGKrT*U$-qzrF$kwm6@u&p)J z_-%B>)y*4OkU+`w;?u6H3DS+G6u!dr@{kI9I>#Mq-K?T;BIkvx_MYw<=s&x+ z9b=QwqJnS$&?f)@Tt_Df2=c!fdeVRFq9At5A#n9RIGnX>Rb2ftL~pcTU+Wk2 zuFbi=(=rN)aD8s$^M~sn%&c@qcBh{YyGvL8HZi_6-u5AHk0r8rYcIzz5Q^5!MwuTI z<8F4rd#9?5H5R4C63Se0cm;T23o5n+;dBfhfE$#A0%pybL6~mdEXJ7bQqYDgdXg}RDHKdZd7^b}_1Y%u>ck8{-5rAUMISe(vpC*EGEmd=$S1Zlu{^6W zzdoCWCt#f4%94*!(akR1FK>xRM>iqA)nwNQoA+;>3hRN@ERbA7WzKU@Ube)bMuu`ysjEY3dCwCA!6%i{e(^ zt|+8>f*nyVD$Vg#tcNMxP6mCik>}td4gm^^I|s%D7l~wkK_!)=DE_>NOU;~j+Iwbc z>VRj|sKh;IPjdy>Yh1^Oe$arx?Vdse*#75`QlOH}>$1e2my*#&BqL;edep2@gefsK zuBECT%%$HsWnQ>V(k@WU+X00>dO~v)kd%?45XWd*i?iQ95*3)Q2nS%9o@9 zvJqNY>EW11a3O8)pt83L6<#ftXU`HdWes1YwCXIBfMs>38F{MNAV#^_qV5e&XbP0f z7JeZ`z~dV37)CUMezD`$Dd#6Xxv}BogYn4lgNH)hdW`$M#CDU!sU4$D?e)SgW2pXU z+l5uTlk=3&b{8gb)7Yn$vfR(6%!gh4EMRKL#x4x{7p%5h<0kue*#JNu1OWU;zx|ID z-ua&SI{A6Jy9I|Rh4>r!`utz}7Z`qU;fJ>3XyV_LFg4`h{N7+c@_?fl!|}cP6KF!Y A`Tzg` delta 1487 zcmV;=1u*)E42cX4P)h>@6aWAK2mrfSMUf3Tf8`~mChqG?*{PE(dYu^#I75a~&XE$H zf1@ZBe);+`oQ|)&8L+3Py|M3 zsk+$M_hwz0!Bg$ghHnC_Gl=bJ2PcKMe}s+;Ct?I~wq>0xDEZxOchQ9_T-Os1hYZ~8 zI0@6aWAK2mrfSMOxbd9XqcBe*gf| z4*&oM0001Ra&KpHVQs}%ZEw>s5dPj@aquaTN`P-Dw1t5-7-fLAF+L(MxouXHIM_~9 z82#_~C0U#{FC7S&G&QyF?s@LhX}c(i~^#*!&qewQeg_+5l%!Jn9L)*-^Uag|Ku2 z6awQG+dg;2y1*88X;v)y#Tfdr#I)s2^@4S_GLA*~R7gX93QGBl5#u*#jU7N9!pB@v zmW`7=#gvt30}NZ9(I4n$6@`!ysn6CNWV`s_;eli+jb5?!!wuX$&(43V_|BWUlj_@F zC^jvklbeGwbVk;!M}YS%e_E;B^~c^hk6`LpV>X| C=uidc17=!*cV%SB%)t*b-X z(llpW0?RSO7`||l=g7rfS|*EINA{9%ph7R#O=W4hiB)F-fSD+`y00G89@e(vUS(xX zIesf>+qT{yu~3&K)ufC!i|G}`)>;kJiQ_2KLi!URm!(q$t%7%De>3uI6?KPjL$$xn zJ}W)bg)S}4G*CM*pKF7b44tL!rhdEGR?|YbLEP%^r{lzP#OWPNJwmld&#+n}V+z7K zT#-cJeFPgGM1#s*F;0>MR`65((+spLgdyOX3Mrt}&swpSy6M{jkB_iHU~Q;!S?qx{ zKJE5Nu~aFRIz{X3e2)0ct=QJW)*(Jl!o_cer*Guw}Xhyxl{C zGk1_Q56)PMFU1QTQ~RatI~(_!_yB3@4ucZ{8zeHk2p(p052!A&pSk`qS4moE^a;M96 z2wghgW|!r&#S~CmoQUft$RL9+T-A=DaL#rJR1i)0F-E)K{iAqPum7deztm<&4_APZ zyqzZ0JWf#*iJUb#S~J7Tju`v$Vn{i%G|cpv=scBRxfJDnu; zKCbn?p`m_Smo!$_($0xZcXZV&HHc#HTYtX*P)h*<6aW+e000O8yI4h&kp&rE00000 z003=aZfRy^b963rZ*6Q)O928D02BZK00;oPSVdaf0UbN90{{Th4*&oM0000000000 p000000IvZ60B~||XL4a}P)h{{000000ssO4Z~y=Rg9QKp005RrsxSZm diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-js.doo index 13968c1835540183b8847917cac185f4a377ee1d..ccc33a2ab61e1a46cfa012a22458cfc30828c2c8 100644 GIT binary patch delta 1977 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 diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-py.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries-py.doo index d4e69953f1be9149e700c4494d52563cca9780d3..156cc4a4e92aab8fece64f01b25484ac18fdf288 100644 GIT binary patch delta 1125 zcmV-r1e*JY41){}P)h>@6aWAK2mr5ORFMrif0dF_6YuMnvQx(?dYvH$oEe5v&XE$H z|DY%pe);+`oQ|)#TTV8Dx@hq~_W8N5{#hU9$VD&XtCt5*;v9v^V9L1%|hoVzZv9qS1n ze*?&|h({w$Iun!TjpK4(-4HU@HxsIIWfSf>)YT$R@O1UJ))CREXZDvg{ipG`q4 zZ~zG|(VKwmPw9?+xr>mUj4|SBZ_#Z`z65lB0{M$|uTCcjjKXrJgtI#;wYi#)M2KNVgmeXc)T307d%z&>&_Fk6=)?WzJ$+<_~^7>>? zL1nToc@6aWAK2mr5OR9ftlH7ThBlfwZ; z0$qHQ3IaVTdLfL7l<bND~y|FBT)LkZT2kp)TYpesjpXHGBE}X89t%%hT30cf=Te2K~3rpkDF>15N?of znezJSIPn~DPBUey@syZ3 z4s<4~ZtDRyhB}w&9!M7?&ajbSZl4q>UhJ7-u2alSiiNY2=x(b_;#=3G3Wd! zPZ$Y}Go|YGhX7X!1$*4x_rC9!y&r#YxS~91ba(Clgg!5IEF4mS5ernQd+PmG(F5_P9*R|(2)>)};ZwmcGoi@+U| zx&&xzH>fiQdQ+j8_dEv2gvR<(;Z-n0KwVBS&q7@q(pwX;Q68Nwd7}R9dU(S=C7zIe zE2EOhABo@%>+E;D=hiE&B+WXm%(|ta->!2S>DJrYvC)>UBL_q?c-H4PP)h*<6ay3h z000O8uV7S@kOdhiq=5hc003=aZfRy^b963rZ*6Q)O928D0~7!N00;oDU{qS{lQk)+ rlhFkeBcy?^0RRASa&KpHVQo-L1qJ{B000620swFT004aj00000mJ$0} delta 1160 zcmZqXY3Jb$@MdNaVPIh3V7Lz zQ%)T{IMpjG*u|sE+~9%Ei-p|w1{G^HcuxL26nfx#|6*|gHM#c%1`9X4YUte+zd7w| zOF3hGkYLwz4HJd}*oO!K-@~Nrsjz@KR2H zonC%{OU9we`-_@F|LQL;`|s$aXeamVI2v6mJz1Y|?tF)TiMFdRb2{yecv3BR?ffV9 zv&*Oa2w-u`Sh?%Qjqho(GY>V>-PGVK5q3SmcnhRb9FR+-pwt) z*s2|KU6{X}=gu1o&SExqnOm!Fw&#_IO1W3}%GT!>R4+)k&RuqSmug`WV~y^$bGEOe z4u0cqwA%UQRP?=hZ&t4GDdU#g9mV@LX}jyZ3wb|tG$m%mo_zN~e)oQqu#b8(*;I2a z^W?*fu1s@_Cv!2`YW{MR5Y~Li%|HE?z?bLW`n*{!1s#?~9@A*ZK9?-)I=fhH>ItW# ztQF3?Cl@eD*7JL)l;&NTu<4%7B6AVxY|#MibLC>&mHu*0IQ^+`!?f1{A6wewe`M{M zVV1J_6GLhx19yexUDcSxJ0{YNm;UE&PT#rQtkuk?_AiT?aPox-4~4bzSNsiCo58YP z^2(BbA9k!vV|>W=bDHM*`F+CY1)rM)FO%~3w3=5r`D6i$__OT#JfPewej0IpUE1Uw27~a1N#eqEo$` z^6I3IPE$THo2g!{ZQFL9gl7)vn_g{`OGsW(Jo8;+iQ^+4Y0hV5OFcd&ofj#do0J!% zGiR>K^xX^nMbvmxvc$L^)F-KbcL|re8^UmdL3F{V_}9xm-p`r7Zer+WP7|kSMsXkW z2J`BS_zq)QTeH$~5x{P_0XzTbfM?ct#}KY4JhJAGDi@=lhF`t--*H4XPdG@jY^A2eLJ zabHM<=ox{4>B46=2TX7Ka?K@2#9HOlpZP25cgx+|;NPjfA@DWBYxDh^xymVLkT z>*TOW&n(xSDfV{WAN$dvvhzrBa;XNyab5)e%JqR3nK%A zHZubQFR)ygJeQRt4oCw*Zem_$T555LUP*p#4!S-_>SbWK%Fn>S4p9#!*8@!}D9TSS VO3V%LW@Q73G67)$kZxoJ@c=p!{x<*s diff --git a/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries.doo b/Source/DafnyStandardLibraries/binaries/DafnyStandardLibraries.doo index 61f8d18eb9ba15c3106a02d98e17d5e0af3d3bc3..5c9347b86a09936f33d71c5c084c2693327c8ddf 100644 GIT binary patch literal 57385 zcmV({K+?ZZO9KQH000080Gwb{TK9@4>4O0P04)Om01W^D0BvDzX=Y_}bS`vnZES5) zL5|xn47}$R3*QxN+FtvMo>~+ESE6j966GbOChqG?#i`>gdYu^#I75a~&XE$Hf1@ZB ze);+`oQ|)&Sa8h_n=(unqMi6IP*2#jB-`qAAUAV&acH-fXftwvCVb0)) zL-S8Jywg=^9PKqW{Jp{bfu8NOnNI7P#EAv)wa7l}t%CIz0(ElfmAAY;*|RK@9fQX% zSL?5<-I{qq#Sdb^(Ckchi2wQh1yD-^1QY-O00;n_U{qRl-?X#P-2ebpZ3O@a0001R za&KpHVQuWaX?GjB(J1`gzoMOUCL%4;LsFYcsk(9Z3 zNLjkS{RIkJ0Vpg@N}eP)&v`NyyMaROC=?3l@4qkRAIg7TPABiD{n5R9_x|uhHR}&9 z%2$)|MKvz_)2GvF{$W(ktFwEf$#8K|7H{Umhvw1Lfx;2aA z<6>ES5AD7}TRqZvxHy|vlkwBVe9{=U3f6v69G}=g77ECM18E*I5I6S{SOdVOh1mII z+P}CcY;uaPPv+C={rhq%P`oLgJSm372_x*-#Unrr4fk3=ffl*UQ4ouuC|Z(!&H<7O z&sJ~Bi}MC4t6_2fSYo8`8S;@i3SCVOANAFXhc3Vn+kZaqWRKQSqjf@~0kqIi&-%0K zY$o;5mhBP-1CjATmTC~(;`^ct%no&2s*Z*i)wycm3P!SJDWy?Z{8%Pr1aw3+6e%T8 z14@}Dk?0Oo%kCuos!yv}Io(#W+X)}__rGWFPY|P4@cfoQ9SN)mb7E#RpDs$rio&c2 z%G;Bl)FmV-&yrUP1qX9yqz>SZ3Gs*fWiop{WB=h6yz+GB`RwQEu$-2|XR9B|@nlqu z`}4_^x9ytdlrp^;F?<<-KTgJ9%IPfT^_b@%eVxRf(FU%Z|FP6&DrIy;csma7I^Nrp z$Wh44g{A=jzp%hBY~&XFdEDICjQEdoI*HF?AY$XOu@_Lg16@yC2%t4az?tQ0TMHW zqf0>^dyYAWYi}66XY-3y)HH%owQmtlpe+nrHH?};#J}=Cz>f-Gi*R@yBWI&<8>p4C z0_S;R(H4)g?aqXV4U2r~#wC>WdeyKRzkjnB%^H1)*1$rqRlJU`ne?OA+)4C{?-;h* z#Q^?o7mYsu(d56Jp#4G7P%rt4h_wX(@S-msZHr$6_@%jc*1tFd1}k3JV=@@8*$*`E zp>D_9SU9Os`|J+`rY%6Jerg=a^`92wVSiMP=lu(@{1osEr(-R%T3N7eI^adIPfFKws{jn(KUG9OGV#EZ++tBW{5vGP2_0H^F?uhkId- zpDodghZ@Nd85JA1%~vNOzir2<>w9P`%s*CGM||SaeIR+-?B+cLvaH{Z&8#e5hHw-{ zx8a8(m?T_KC`8oh3X9=}iHeBBEg{5BJ34)dXHw!z0ywt+Z0YwPY0vcJ;<*nj=P|K=YUa;N% z0!?H3Z@Csjd``|XuO{Pa49!{Ob{j#MMD4hyWb7b}{|w2-!uZxBF#`SdA~6e)FC&NV zaXCT4lP|~^4s1Q$Dn{_H?+S~NFP@Pjp6`m0O63cr7+}3^WJY3x&~p#N`O|Rn>v;Wy zB*!Z0vY`=MZn%#8yP^S)Ar;8~YKYv^cl^;dG+5c1_i}NeauY1{t>#YlGPbQCGn-~t zLOh0*zmllIp^1=_n3yM`=h3n3<*em@=}+g+CTs!TbzG@gcf&YWY+~w$p(lX%GJ&rG z83)Emyx*1p!hUtbfOtB2#>6sMxB{U7GI(A68c4=_O_n^CE>|)VC)Q4q8ohxfD>>dw z0%zcUnNBX5+Ek^(Cs&`oGmJKTVUA&3zVCCUG-O_PBR| z!Y0m=M6Qz8bTK~b&&!w9aClKRWCA~ImcDFqourm{{hl0C&G1Fc$)O}r!`qh{P#(%zKI)6JsRa?Y+5L7&Hm-5Uws2MFU-V%@( z3NktA+Z3%8bhUXd07i(!ULh*i4Z(bPj#yn$#p5vD`o-ke+Y+qYGrMi6o*d_j6lhsD zj!wvvByL?{I>17bl(NZ`K(w`QuizgyDlmL){ z2jgCE&H0*9ZwjAY18z`ClwdUKha+jmjs8V7UvZBDz{qCdcv@BT^e<*5UTDeZ0>2}* zGaX(V(pamyt%gL6A=#05+UssHj^0dXKVo1pGb8{m5itr^-`5P(8Gs5j;zLmlxtKo* zF@H~pnbd#WN-ruHNTH6>sw6CBTMeSqYoVWQx?{ZQCn8;Ora)+F`N(JCl^YZ6yt=$7 zXMgFBtJ#M}`;%Ceo)IMkajm++C`cT(i}oiVB?p`TnN+j+&rElm(h>mz>$p3V8ixJv zteH(br{?KwHaV-rdYqGamt*0isCpeX&*wAtAF?bH zb$5MBQ8X++(exXnRP;=k+$TS6#&t$PZs&jw_!!%VngKjdiIRZ09Lsn*Eo)WPf?u^= zmslrj=-bV*#ux#_d6j-X60R$@>a=u}qtC{i$%y+5SC*YASAse;Z6a{Dh>}F?7@H`8 z+!{lrGswxYBJvOP1p(L65mJjIm?gpkJboQ0VNU)i!$lpKN#oW)TLlHks5~7?=Pm%k zt08+ufL23ic)iMgSU-9 z%KU~wXS$k(3tN~i{QM4n>LE@7yMS5yBzS`e&WC+xZD0_!87^Kej|~p0Ih;#!>~`Y0 zE8)emhUJ2H0twVJNR+AJ$u)zG>Uj`CTB!+7qbhq6MpAE&#INxQf_Iz;3g_960c+HUa%K6@5>;P$ zODJU4oaBrAbH2#$4|oEW|6ItQ+r{7zXJpYZ3pva}SBNhx@YVwTyur~NG>gG1eQpn$ zwuzrx0oJjXkSeD13UwYn(_=r0|x>Ojw5hgYaB<9y%8PljcHvAADN)I?C#e( z_@C980tf!1GfPU)h%cV4r~C;-fCI6v21>y(vPDh3lqE5Z;Mdlq3&UnlxX`*Ku=hMI zJS`pw3Ls1w$b`bSOI_HzcXrxC;E+?%)d~RDqq|G}$wcB=&948u$n9m1ZBrovg z63;a6I3n&`9~jW_oXMdbPwF~D%K}3u8SJ1;`Cjcw`>6@vccg572*m~1lk$KjF!}RW z{0D@H8QVU1Ps>}GAV6VVb^`Z4;ZW=&#SAW_!Kf6N7;|YtjGSnggY#hZ4UBs7OPfkR z5o0V>nt@ScS4_(gz}k6HuPm>!$PAV!(~0h!VEzdIwqW-_yxmF*qh2jO zpr?v|cs`q4Fz5dimNQJYv$&`DsXsnjc>!~+b=|wpfKO!(BJ+h1%HG>`#aCuy-ojW6iTT0*&zj04BD~?D^#~*Iy+q)9JPIbn8Cf2B zY{>GzN}W-6F^R~?{NK&J@GpZT$FG@2kaAxU(29eK3%G-6uKv0~+LfUs6*GKaN!lAI zNqapdY3C|QJEbJ;dP)MvF~6ynwC_ku+UseFDc`{}=TfDB(t#Pc+x!KLH!(S$l}P>! z^jsMA!np$uRmQ-X@#J$c+ z&ze<*OGnu1nhOHiI;XKc5J_2NUCF33E~#+hm`b+UA{jvZu2P37k(ldHqKJj15VQl0 zhshfZ?6pq-QyTEK3&N3%2aLGV5AnH%P~aAz$@sm#1<2bl93>8Oy9WbT9LG_i&H<*+ zcvDBbafJyKDKpG6DawBhTAna)!T-f_F5~9Vn)NgigW6(&E9mn7in9-*&OQ(621d#B z;Og!7-Vm z=`!C$fx`N8XX=yIo;y&UNKSAw9c0YKUGN%Y(oBCv9}rQL9ewrEPKbch}8gX zdkqN*Ak)E z%i?-F&FwdfK@AbM{~bh_WBF^H(*Mr;nvN^qp>_!CeN870&s`Py`j9wEVDpore&kXO zG6Jecnre7v>K6hG^gwBmJK*$l>`X1*jTFyD1kW67TowVXBP*_>5v8G%$YqQ|@ZOCN z|E2j~6RZQWqwdxk6-P*%VXLkq5)b%#;;=5l3}5KiDd^k#{L2;XabqJ!y$?c#}JFhQ6ghxir$eL4cE;W_3>t9bWfO6UTdQ| zIBBB=4SB~xkiv}wXEQ+EgEhjt78bc7S;pXaB9;)TsY87UCm~xW6IwH5<|TNRzX}>m zWba*;tYJtY8?&)ZPxFL3dl2xFBq8!Ox@+co4mz5Zaqd!N=mZq!2}}mKXw% zd^u1oCFF29Er%5^g)h7^YbR?F6@(bQF@nNj3c;ACS!X~L^84lCKqxe_5(<6rMUYVF zi&ba4pXX4C?}WL-cI2=zPppcE-M$OiH|dj8T1m4I7f0C=a`ZI9%4k9>s}0SM^LlGEnH-o?o0*7?)H_aM4YKYWylQ7)E8(7{h@cCY*f>s&@6PeAB|6x zw;3vQkekFlKC)Z7=I|+-Q>2$NqGRL6*WWl@M%HnprwNrwTj?~6-b#bZZ)?pN2A{h1 zF19e$*zUBEk8FIfz+938-VvFduw2DW(=>ivz5g)ZKxVftFF@$7gtocBa5OEU-GrsM zrUa!>l48Ue&W)_D?c>>ALy88U%>>wvT3rsZ`9eexBZ5qi>j=|MK4;5uQ**p^LEeHn zhNXGCl1xi+O$p|jqq_FK=0y{xO33-VBmOqvwmx8m8li($G!S#LEDYMw3;MKOJa*z# zZ*U_7LdGfAS(hbHnpU3`ncq?jlmPt($dZfv;GGlk<8@rw%lGX6>mEE%0j;?0r7MoT zV8xQ_vWB>fSzX4dw|~4Nbat%H|4$#EgX%*7RQZ5ZYqJg%N-2*!iSthleOSsUpgBed z`jYTGm(6TQvln=)KZqu#WDVXq*HL$5R zOm&>P9lyh6ikmPwcQ@AMKGG}A$depmdVIlb3^qJ2&%DG${LEisRn0iTolJJc6X=+cPim^q?ebJ`H@NFOaG!A zpOu@5?)X^h;gLyTX@sK{AaSfV5}9xkj?{4F3_@AI4C21N1oKDo<3dY9v`F87n9SyA zQyl6;b-&CIf-2%!L$G0ViLUgnaRl?LJPPz9j}sCji%zdmArEiEKWHO4FrQroCo5>N zLM>7R*S+1C(E1cLsKAM-V2DBB+p-yxhvRj6SjT!Y5FmHsJ;+x{M+gVp@prgC#WHaUn)yX&*NZ)T*t2?0Y zfiRRw%swgXN-T?lQK8s_a@zdw|1jC~s{F~6lolG8*GHXSNq2UXbg3xTn zP;pO5zF7={7wCIx1eZvWthL6(!qAUH-`bAwmn=axu<5Hf_3JF#4trPI*quvyK7q^Z zqGA#z2Q`uV2JSe+AZUbrXn?4%$VC0x0qnTgBw22F8FfwMNsBxV)Wcmw2(Kz)2k_rVwXrU&a6@{VOCfbaQ59NVr;a(!wYTAfj11LLi&RDLCR zR63pf@3&GS=UBE}9D~7Z?E9*=F@-hz;RXso1J zW>RwP0C#+uO;X6gQYKIOR|lKK;1L>$SX%lEa}Q4RoO^Gxj})!^NA^8q;#2a}I+ZU` z)wku3(0A-}m>M@SblPaeLAyzE>u^`5T}qfM&Idr+daO5#U_A3W!x@-kPrSQaDN%$N zZb|vCD2q0N-Qcr3aL9XZeD2O1*b?@(g;89c3UI zy0xGe|9+2>^E0MdpN9NS=-EFr(yCFY1V3=MyJnX{ou>Hhc1&a4>6;Lt?K zZM)o$FG0}V5w;Y}xp=n3Gih(o|v;V^?b1RnsxenoFmNyjS&Ak^_3qQ_U! zm9)i`yy$b~jo!eLl^ky-fkzjUo-cLRnf6B^R^l^@D<49p(%G&W;|OJE2#R!twsUqQ zk*nnEEU?j}1y^lS4PtlixD%o?iD@{oxyXY<&qvvO32?*xVhZmaGfUsUCSu>GHT77I5?8yqu2v7c=yhKYsP1IJVw1 zyS}K#Wq;~};U}O8F#Iuq!S7>WxDEMW%v=AV+^96&7?FQqewlv}O^@_+TFpO<%6WBm zZ!{S$F3RG~eE85jeTc~fmYy>OhY$UUY1OSyh5y>~zqx=UbZ^lRYEeVi7V#!hmTf*+ zsDXL%u%%0`(RDgQ+@+&m%Lf*Swgv$zfQj>OZ;Fw4A8$=DJcjxZr5sibX<=;0dVm_h zPlFV40sO99n4}wHDj*wsG1Zva#+X}5yU~Wf!ECx=$KjL?jsevuF+#>Wd{~`1;l=h7H1`<%|=>Ono93__BF$oq%O*T-$9dfL_|?WdZfhoY zQXSNNfq9=y;_QC9SSD1Ok7?}I@`|42q1bu+|ND^ifZ5heU^lc%9h=SfZ{n7A@Np+%}C!JB~=3K*a7s=6_de&LdQT z@TbJ3K&sOBCji{ztQl- z$3=NyBhIRA`-pbbS+yx2k?KN@5%xoE$|3q)0$-!S#=g;vszOv-nFH=5b0)Q;9(&;t z^MLidtruH)qNg1x$;gd(NU_f`dnNadwF2zAFY$`5-94lPB10hZof0Os!<4mlN|P3H zbDEE#!R6@dS$vqt7;0G8=(yrq6k0r58S>}_*zl36pX`Oh&KM2HoL#6MoHiOf*# zDze@r*S|(44fq2V(zQh+vvt`iT@rxBV%}5>jsNiF7R)i%fUZ(l06j0CUI+KKg?mQ! zy(a2ygL+1;K9FNIg0VN8cqvanA^oHWQemS7@|~s1x+kvUft=1qp49nR7*+9Wtf;sZ zw^P3SW5X{#gE1<7gO)_)@Lqa^%9|@HxuDC*kPG{KIvm1>4xQXXG7|zjY?mV4WwJMI zv*UgUF&z8*0dKdhn|&vneFtJd+jUW3c2shAGYn#NifKCH!w~0ovzj_XKyacv+BG$!y|}F zMGH;Dj}$&Uqe}?6$(kUvZi4ig4hhPjBWOrB(Kf*3P90cy8!n%#SC=iZG$t6S$9rJ( zOFW9P3R;YFaEuv{&6!+R@@6qu-<6D{^|xK?-?m-JNMPKKx{@d`+LZ+0ep^@4wp~fv zb|vk4uB5$|D_L4b>mZ@j2q9Bn>81BTpkuBif{!Hzgw^*JxEq2#r*Voh=*Tb6yc#9i zX1bCnto2+8b0b%ykSkH+Nml|M1RjN5N!yr3630LT=wH{B=-j7_OXLTbYr2$3P2rtK z9By32khV_GNtg^2e1Zw}WGh|v^aLdfaLv5>(kzJj(iXK1Q}bLepxKL~6j%BNYZ-6*6JqYRxGg>_=IzD|f!DYszX z-zlB=MyrXGZTl8%E?D*uCg$;kq2G8z9o^DUzVX);=jrw@SCK1h@40E9NF7WRN`ZYVYU!{6f5Fj@q7}Wb`{VZ| zS*7prrPeu()X|CWoTC$t)#M+W_|7>tu@0c$+9NndOrXL?TYhFiz*Gz=cbiaxH7Bi(^YlyQ zoZP9{yLT2B!MTy&1HvcAmEZyg zU@brFX(b<;m~RzIFrHa8bcE?m%@nL?MhV}-O8a0bf*6QiR$*y0ZH%Bg?lLG|LqF){! zF*mGE{I6QBap>Z|D!cii3+nbEGEGtYUZYJ8Y}7uIL5}7g$>5hepZ}wrPM**Be;b*f zEa?=^_bXgqKtuy}Nwz%#aa02$1$>*j*vB6R2JCRnAFt*g_%+p}1$iHO03y)W9K>b0 z3BpWP{Yf$Ii*GZqf4$Qhieow7eOU&^GU<8AyUg#7kYCBzqx1yqu|&4JBXk`PnpY2j*lwbxzFV)RUV}TLz_k^)+7r)h6xnyvMfQsevG6KqIX4BmU!DTA z#dn|NMSFqGllTF34}yRFw9$sDkRR8p3b^g$fxkIm6ZmFvc2>@2lW9!~VPOHO-<8?K z62A-mxvOn?eyj%2wga^70c{gE*cvg#*1X|8su1GN?h=g(ArEg4VFi~9PziUsWxE>} z8!Bg8^Abz73V%>s83BsliomNv+*5nC?f`9PfVMY4TMu9h6scuIqUb8jkYr;NInoW| zW@jeOyZF=H+dK?)hN$q>s?eq9eC^vC%IXr1U131|;ciQI_$h480B%aT(W9osvc_<2 za=11zTstsaJ9D@;NnM+wuI&%kUTZjyx;8~!+h=B*U?wp`N4}2UIPZA}Qo88Ci+a{; z#BLu6RSlEIV!MlMv#({omV466B5!+UVZQMx`Zw|?R>>fHb`0#Y)o_CnY>X{>kaazw z86(C~Lde9O#Xb*1b7EXJf$&m%M>r>)q7jkdUFTNPAKgUyqg8b93ce+7&P;@vG$)B< zTn#3s5)L_})`Jr!*4Z2|z9uuN=Ez^BIR3+>UoYqNAE_DZ=B{ofbwq*jQb+!`Du`Pk z?2q=K>(SMxiD1qMB|zXC16MpT6@x6M9iBl_wHf#23U`GsvZhQ6e{?Hrik6>+QRoRO z%FX&7%hLb$3iXwh2e6@O3n7u}>JOMe`e*Zk&UwA4=JSj4$MLZ0k6-oYcG~ON(>Fgh znvnFf5E0M$)hkwt>g|L;(c3Qc(|c|<4Z4eO^4=b%zf690zGRc608roryyz?Zw+r<*BZYx% z2y$8ill(i2HT)kxhXrGa)oKQ&h}qP{Tv^We>(h7giL)=v8ep2Nru_e$6L*C@&LMh{ zVg+uC0p1WWa9gbzApm;P3o9BvQR9wjv(mIuZM=>2e3q=QH(^>M3S$kDLGC60kRR_Y*{E5e27>4V5O-VrU0(PyN@8G00IP9~H73J`dG%-8>C|%y_0jI=Sl54nyu|)Cq8;OGWd$uIB9oJByN361g5< zl;bU~$ZDR$TNjs;U->IM1aGd1b0VgYL&bhO$Ms;Q2BWaA(Wa3Qh!Lfr9MwfJ7>Ri@ z474=3a^428w0D17Zz*GkDYmwKjs?vj?!g19KK1BWq@u%nz9Qw zB+f96a5!vmZ)7099i|YP1kp|f)E*7S(yU<=yae+R>~Q4FhIl#q6{qGLn_lIFaMvsL zuUEmVed&?-b2Up$o#?@;b}$m2J9Fbddrk{{p*T6GC|P)uba<_Y=J4adSC=zCL)_@1 zQ6j?xKkgi!%u-XCA9bzBsB7g#U76F(tMYR~JF{jWrLT4y%Aemqw(%B^V=CjHuB>Aaw=Y+jb$RL^<+du*1sf zuyQ-(nJfbB@!tT)wrSpIwKJD21C>V}wIM&JVYP}?7;p;C3d120yk~dE%FIV@6?j`Q zv=m9|e#A4|Z`ca#K9^WsJr;}*Wh30zR>6O=&UT_qBS!zliK|UEWKp@5ZsNt8z8V)i-7Ghqx1xF|tpj|CWi` z?JPTqIo#0B8Ez9GLK@C}pAf84`03BdYy*pZSftQ{0Q$uP-OV9~s$S`fQ#)D>HIuCvHyf`3%FDH*Abs z1&Sa=OhD!)%$mo^F*=oV7P?q#9M38Bv_5k7-AEtJDf zQF#l)(KIq=F|RH!${A$D;tBuyqVSg*&XPj!BL6gD6gws=Gt#V^;7x`59 zdv_aIe|pW@L}pKaP_dPIamugy5LmzCtW@X}-y@y(jw^{)kh3165Yl{i9Ps4Ycda2d zuhl^z-0&pO?#1N24#eTcR{JhbV9tzBR;J&f!zMCiD6Q*S00<04+>+*URKGRYY+2|S z271989$fytb#3NcO~sK?ac`x|Q0^d{vEu5>bk+EUd&MMz10?Y)YNBT9g?0vuH`!R6 z1d(9lznYABN0K?Ol~O5T2}iAPoK+r2&c4UV(nc11U6kf_!i0i3i7yOE5vCWd zL=GdUXND7e&3aAfnT8)rze>NiV&hc9@`bm)D1xrSZGzdYkpO-Mvn}jhI>o|ZilhPQ zT9EHGoE3LNLp!s0TvuZB2$8f?hRE<1SkmDl2&S!_Mx%P=Wcf10ir7!Nup1gTWat@a z_{Uwxk*Tu?UQj=|?0;UAW-{fm^m1N$TTp7%#i!SFWPNn(dV`hl)#H#RuDn=#>E$xG zRmhCK9YX34Rq3FcoYLLBOE!07a>X`b3thMrWR41b)@71^2MjPs-8xp6NoG6Tynbfa%Pu$>dVNQLV*#y5${s_pMV+PhvoYxxI)(+nE?1n>(J52@}G? zXi3O^(V#TkzgF`Pjf3;>VxhlCRgW4)rhVFg4$ejz=h-l;#JaUbb6x|ff?zLLo zj(e{bgAv?_k1T1)yHoA2a!D?nn4Dh6v%Bzw5U#kigGjR%gX{R5Qf#}YMK@LE6Z37* zDWxhYMX15AnD%sR?Lm1NOFs{_aW8SSuJpg-X`0aq`4rqCU2X8j%ktSQ@Jb7qwGcj9 zHFt1xS9t;gWUp-6NnfG8JGub!Q{Z=`PNi)k^{%hXGhcI6<{*W`F> z{%_Zrb@JN@AwfHcaE2cY%xr#F-8P$nzitj0`nNqYqpSAb+A5q!)#k`A+kRi zMA5Xt+WwQFj>u(bvWI4=3HQ_Tc5n^{+#>(QCSqktEVKtqdBh>%y^{d7>rbWc(lTuo zSI%!f0=1Y6XG3jK!ns#1>X>`mj)yH*f~i~uh}x?f^Gu*b$*b61OE*y8JPkn|u7aAu zp8yS5C!A@KzmoSoN+#LOayPre>#{4)<3QRz_!u^muaf0KNv?9Glu`)#QL=oCc*BLn zILKfLys|K4Va1PXCk<@WV{(f_pi(hhDq+6tWo;yaC6nF^<~f5jjL2lhFR}i%lbIOtH<`>Vf5q`g&Si~Zb$;&8P}*so96Mf1 z&R4oY+q?(cLbI68RYV%gxs6Y43X|G%TUx}oG`Ati=Fe?ySDnK%nLq7)tGO+uE5uZl zQjwt01=?xla3(q1nOXffP}G}Gh5rsyU!3V{PJQj*)VICC)R)bChIMd4l; zL-xdP_G0qB52u;=tNH4(6#IFsYh}(Yqt8jp!!&E%52(koPf7DF$N`&lWjc^aP33sh z_}cOFW^inpKQ)sz>w>*A*V7}>HhJclvHF+E?D>rSC%Ih=^^y`ZgV#Yl5@Tv2s&+2))?|AvWE37#X&xs~lt4##oB7Oum%zDGVR& zBS=SAbC789i`ErCcnpcSz;lWY@w~-4G)M3Y4lk8DAcp#wI0p{3u3)!%lP!hkGq`S| z98&rQe{I#Y1(=SuV(N8tY(Lp@ccpx{v8DWmqFqjxgqf-02?YKS$AY#WO2e}{TdXIQ zAHNOkYO2?o_rz;YG*}G;SxP7Bikwe zQU?u)-H2=%q`s=p?jbKZ)+V>Kzy4wkr0-5PUPSgeiuP%Hom3Mt4xovP9PYQTE5z6S zMrd8<4qy@-bpfs4kaWC0cjLD>d9fJA4Bu>x#CeQGBWEt$Iy`SV4%Alw{(sc9-KoW1 zxc!X<7v1_B2T9!eW+*BA~dg|{xY zXJg4Phmtskzk0`T*EeMoRD?Qq^@ssFVi(H%*Zzp@b`2ucglhDD0=C?-xUpd5jI#MQSx#k*sYK{+@YBKa@8%(8tfG%Q z0kRi=CtiqIka$MTiW)fkrGdGIj%gOHjpHX;trR_~bx3avchVY@Vw*d^wp_Z5Uyv_g z;h=e_>uQ$zuN9hrBYdih=ygpj$f=sd$Jbh{e@J!;p&U1KD=Hk);E)0n`WsT;hUA0H znl%1yerBn%osfyCvuKHii@L+RRqhDY+HG1IW-FL`M|~}Bu8({KdP{}HrZvs=mOxwl zvkbMDZ44W5Ll+o#<(fmdp?PY9x~{?Bkom?r9h!hPGH6~YQa7qF#;7P*iO*|WYO~by zCTe9jvTpScg^^1WM#{+^jkZvuEnrdY8f+4d4F*9;vTDPCW+jwc1vCn!Mv#-@Qziix zCeryR0kMb0mzQwAqi-A$8ztUIsm&6n!{!?%+pu9` z_D13atiL}Jf=lg@#JG|#Hg!R6-q$K6h7VLanExRv-wMTY4mU$qhUxWX21jP{O|5NdR6DTns39vh{^s`7cI+vR<@)v%f}4^NFuA^LZo>!G zpdni!QNy;^uuU{{a6|*dFht3TW!y&IrhGJ(yS)!p2KI&U0Fe!HxABG>iTl>aSzF<8FO1|D28BGH%b==C8h6TO?>lmA|K8C7+&p!BtiM}8 z^^V-j;9kX`VS*ZyBNREE$%w`S=fpFD(n$2e8gyf<=mO+{M$|eSsoNaN2kOO*FN}`Y zh(gis+6{Dh8UGyaAWm+5*>x@1xh%=(9Fv^^=gY1em0gEJD5r#@nYz5ZSfnew;8HN;H zY5Eibe9azmv?2#UkVPIy1vKEJ%>5bm1Zi9Oz_ap>{46)0{HW6BP{?4Wv{)foN#@7Y zfQu%X2l&PP?pwg|A~Jm+DwTJjT?0*M4QSVhdtv_h9@$8SH;GO(Plv;q5nxwdB~$hS zO3nfDTR2LgDf&?p1vEYP7NF9YFn1~4!n*drxyc{^@=!N0P3gJWzAz*cMqskWuvCa3 zsJEx{_~i^WNHW9W5V5O@uXAY$hW-8+jmRJgt_$5!T^+O{l-L}k$#;~^VRu-UGtAdf za>DfFpg5k&(|X#%YYZ5R!Ez1H^#(>vNJIe^^1a>RP-GVqZo$NHU7r6cdjV(B2AnaL zHUVL0LF!rA(^Mqzza>>@E6FH2ZLP>4FHbAb0ImdWsbouXKJA~)!Mlrr;$k#Y4VLUt zSh7treg__Ku5>L%^!W8tURPVr)TdXerJM^ayk_$l*Rwj@xNs%j4=|<~Bk@mktzN3{ z9y!ojsDEnYJc*{(hFa8iI1&*Y-92U(5@8ha{Qmb^U##J7Q5iNs^V-KU;AOM%^*t@J zxjZA4I>Yy5`qD2b;?9T&3}RY7ot}AS$N$%7y_ve5Y25h(-rDuCXI|8ew^j!ngkAxj z+0j}oS|Y+8jX^4Y>(lXDs+%S|7_wQ6sS~vU-b@z;n}v-U3{Dk=qPDy%o*`^IBd);< z%hPHsFB&u2gsIFEqJF$>Aml`gyibela^t~Pez;F}2sD$7Ng#s_4^Xl>6hj9ql+!5` z$i{Rq*iLz%8@+<2wuqfOa{K7uCYo(Qwk$1YHZ^%j@D043IM%pzE%EC5U@# ze3Ko*+sl1mwEArLfyzBelu8_7c=4~tz(8Uy^64*YV56S!NLh<~9n|20Cc8!Ty77ik z;warkWzslPtJh?~DTR`YO~c!O@g0jTr7WvOoC=#QtvRm7E9q&g%TlDT0n^GFC}>)l zI_#Pkp*M+KRQ_#tzleNg$4ZFe4W>*0T?>GS`Z7ued_XG!XjL2^qi|ba;u%3I4`$bg zSr5tHcmBn*aVxot# za7gnlG;Z-goMkaYswZdwJ@TrB57vkC;=kxUMEjxVqU_fug=RnZ^D1@@K68IRt3rTU z`gnMn< zcl|1G!{!&asPjhEbeuAK#NaviZPa8Ir&{(pW zw=$IKac+UJFZ^~k(nKPpRh-Ml5<*a|RF9^cI~lAfC6%q?DX;uPA2pIfI438w{NN{4 za>&hKg}lP%BVT(16X6$)0+D_4on&4XsPXe7e6oNtiK6} zmhxXag^*L~M&(sH^a-I~WEy)Q@0e`jB!GI+lxL8liFSM(jCzeO&!9pX^#KNN^WDQv z>9C0vh~)afx}eP7{B}vphl+dQPA+tdX<1San^iD_bY-8nxl#vT0+Mzth1M>|UOe94 z_}lxpqdk!=_jNI)D;aB}?3y^XRH0ndrVYK~&#Aw!g6sVJT89SX@&R}@f z2xU5!09in$zi@`}yUnorX)zx5N9B0lzYyPz&bPbqHkq{y>~l6`eIT?`itKIm;+KRIvc6U{ zXxV*(1$=5}c@Tjf&=PEos)%p~oBj<8I?fWQ;XBc}jseWD%bep3N-UPq65^-<`JP}8))t1Gk6gXnR>EW)C+0-^1!l<=^7$F5d z@*Db|uavqu6YjNmNqrvJJw`5%ihq4F3?3)HArF#^WDq_{-fQS12Xnglo=s^B4vQxZU^WQhXlt6494 z=#w{i*`Ix4`qiTkFvBjUMR7xoEx)(jlSn8Q^8a}9?U98T8I=Y(qgi_>iOK^e4u2~R zMzVK}6VNJMmt}r>(2PO_wt>_JP)saq>Rdez*3m|z5w&%KP*0q|gBZ2cCG16mr zwbvzv>PjATdc2gKk##jVE&-91WoB*VIocXv9(@IA@1 zokx%MJJk4!Z3hPjJxZZ^l5;zId%L@oUiBpN4!RvS28Dv+-)^tV2BDBpEPS-Pv$snr zTTgOvXaCVb=P{*oJBpD9I|sYnN0jF6NM3e#4|X5z>{I%;BiY$|y!&|nphs!pzU0`W z-QE3z-CaIj=keZNcOSU-l@6A&f}+Sdd&(>q{=qY;i5Ampv9$jtOPSFhe ze0K1xn&ZLI+->7$yH5s~dm%Q@K~Kz0OyHl#m;K?e911{ur*HheF?&+X;4ee$_3WBO zy1Sw>`1ilZbIB(@9Z9$Ui7iEo8K0K)GQvXglaBRtOv$Fqa`|=wuPeTkWj|SPX_Ks| z@+sDVUj>Gi{n!Z6<~jyIcFHMCUt%eNC~sU^XLVndH8q85v` z48)K99gA<;kZ_Zp)x@RKMLK(wnQlyCQQbP4jANRK8D2f`*!AalEI7cSA z+?)-T6mS{j`NG{0j;jHig43E%Y<=7u+D8Lzv^lhqt)-iQTd%KH-jJFiI0^*qcp9XS zY93k+#&Jj-lgc=e00h_XJCvs2yG&Pe!-in&`C~(1_Jpztu=V-|XB*i!a@GlMG^HfB zjL3c|hF^Nglcm(H!1r=C8OJPH37uZjYgW%mhZ%7OrM;G~hNMESi&kL7B;W&cSdjtO z5KPQ9F1^{02yw*#CBXg;Mm}S|tfj>(y>VuO5+l#Yu+8J?rtlP`90^ zy7|cZI_I=;r5w~gyC3Q@^L4@1#9cxYb$Ee3`Kl zA1x1?AIBaxmb*!@WhZ4g4yQAceYp&q`?#Np{)fD4PhHF)DWSyqrR`pv&D2)eJL+iz7h|jVpEwKcw=_- z*{geKX)c*#-ST|;PO!=>bS(~@K76?QuE`eM1d6A-4OJOuRh($oR)$QM|1r zZ%yAK8-~^#l}{OOC&>1z8mjAHumNCQsE|;qi_)hkk4>a$oX2G}NF= zHRz!RJ>5VqJ_IqKNnmam6}suJWDIZ0TCrbFJ3TZ5#K+%(<}ki$=@g}enGsNKH8Lu; za9}8+f)Erb9tc9ze!WE@T#+PI^1yS92-LI5VmzEB-J_-XdXga!Yl62xW}DOFJ7FHV z&_$((a!h`7;S-rP1&}m0f*fN@NA3D4R1b^m!L_I};OOG{WWXe|^G?hoLL0QljSS~` zWYNP}yc1KO7$Tjuabgin&cKdHqO2TP0yPuKAZH?>*tAU{bh=Y-A{lUv+~E#5G?4%` znN!JN^QmMfIh73Psbp78B|En?l~CM`OeH(sRI*D>CAKKF_uTnrQweIYgBt9(6T?8c zWjP~YTF0iC>$7ys2~JIiU)$w1!}IDMdun1lyqg0 zsB{pT3kbC2Ok?airw2Wc1)r>bWa!bxLGh<67 zb=ZKzp?a2q=D5sgXim=fNumg0g`Lm_N^6Wa0vV|7;QRX^V}#Q8$faB&@%Dc~Xs zw@_R)P{{yok_>!<{cf??*8WB`Tk#0%Ik7fmXQ$OWB3aI9kwl11$(e(@S)&T#EWFks zWu~G{o0LI_lmU=}w@n8YDZ;P%GEwCC*l!{Uf?t$6xT)>H7WSb}gbmz)Bs2=+JdieUDi5DI8x- z=D+yJCRQ!zC@@>NsVtbilyUTgSO*$5v3K{M&$=8D(2!Fu{kBL&^8+dDWsiJmUr-l- zjdmdhF~VKWf*3<%oyl%rPu{UdRL@j!B83RK1NlBIL~R z9f(<|H{IZyo_S+0AK`_ZV^oXTso3aYfkI%>KogKyG?-50GT7W6$jx-<7F(R!crzxn z98$XeqaJ_MQPI%pkacSnL)Ox-JrtU#ajX|vAG@b$!!-djqF%Ffw*yZHfa!o?itwi@ zw9C`P>u&sYPcsLv#Y@3o`%%|_1pH-cqS+ZJkR#ce!Nxr11Qe!(W+gP^sLIAz3-Hp} zO6N}Hd82<`@B>Fh=f=?wq|G%+LOorTLm_2kZw0kKtgAs*mQw+;mkJ!?&2+)sE_QSG zYD-eo!mP0Hv>ZgsDWYtdx=D*C5s&GRsuyL**Wt_7B(~-~8GT{%Sy#;(VSUxBfruiK zs{tBVT^-cwYEGuMjV7NgM zRRUdkDqk~*iKuB6wL+r;jui@x-b~?wOQZ;M$hD0z0Hm^R)8ST7W2EZ^_2S$Q9pVD6 zBgHlSx`}?>K)+t1U+g-cJzIV6`dxPp4R?6$9p2pq>*ciapfXDpUFc%>9tBjFi(U342^e(NAL!bmbm zrGeGbKq8!rU_pj+y_(^i)<-XZ3p#;yB4$A)m+Bn`gEu7VzJf*3h?vA0IqcwEljWfu z815XfX|&h5h3KxcNoc2)FBr^4XeWcYo)ygHhjF(S9yui4K@5}=;-v0_g8hhU+`j-> zzM1!@b9Jas9~z+UjA{gTRrsY?!MCRmA3CFn-S39AHSRQlE%NJY%RHzyO`;4*Xv<&v z7gfFTl2BPmbuRN$@8XAK5`2aCOit(3vSn?{`}|?=31Sa9CYWgeqX|g4`HQdY}se=i?CZxsjHP2j7 ztBnLB;UFW{ZXX$e#|v+XPjSZjpoJ+5XD6RV6$2xc1V!(ax&a$$YEN1fEI^rrlgoJ`ML&ETp+i`6l?|GhAEyF zA*Y4hq)!HIP+3S*<=N!%0U$wr8|0JxcT8P0{i!$-j2v@}I9oaQKUwZ}tPuW$S8eXK z9)F=`8Kq3j;tho_7~MNT91V)nz8z zqpDPKkCvAMJeBY8@roJ$qVCMxAnN0(BBetI`JPvY=%U?IiKq;Odj{dIi*OGRMyPrT zs%L*OMzBt)rBNDKf28}I8|D0x0OY9UmpV1yT{ za1PAUh%s);RB`&pW&dn$9oMtCc~tD$=k_wWY1a-XxC!SF^%4ZL5&OBpkK>_uZ!|sN zG3Dq0(s9vLs+a+$5$F9)l|P#bQ-8 zydQ4JZ*vG9n-Bv=Z4nnD1rdaUab6^=aJT8VS+mAcQ*51>&#Md0`2=yJY_ZGOs(EFI!I=^1;s(>aG|(kM=8 ztaHJHf_8|33Xa7;DiQ?kKy`R=Ga!i8ak2@pbt!_t83)o%1wtOm1rfyC ze89tVNjvAn7PZOd9OybxSH9|}!85d8Gx{{`8tN5ItP(rbK0Id!*lAYx=vJh? z@oV()x#ZSyK#kW)Uqla3(~d5@v&7ThQXk~b)EXzL`Aa&ccYJAJ-58Dd!>f$wY655R zsdN!qaN*sj0QDX);s|^IVt{2eA;wOy{BFP8|J{wRTpQ%5Xf@h&EhIKMgZ@MC10RpE zPJlf73#lzqmHZ`K?ouzTVBu7PzrxdVB~9L8!Vzqcu3JY|=}6!843WYUNv4u-a2knu z0)NetyS7P*FK>}TobHK;kMQ6;2(0=S{1~Z}CA!o9)@JGGByC?ouO>;(G5d*NAGJq{ zg&7S!C5ivKL{lVNw}(fyG(t4%BGv=2vHP2l>d}VWf)luB*esfe?AE`)zPyfY#JuKL z7qto^C?mh@))k+23q-bgr*`g&r?nPDK>=W9CKSiw>iWU16T+s9p78p4hLZ}2b9|u} zBqyS9tfqH{xEsmiLA{_Jy}VOK#@*{$c+obH$DQz;7{S8735giR%bsw5BKu{osSw*F zzh<0ay}O)`GM2!hoQSpWm70U00u#lWrhOua&UDjt!`1+=f9ttFgV*VJ2lKi{s8DZ8 zq{@BNJR2;G$!A;Qo~!)$uJbt6NqW@&ZgWI^KK=k=>}pNN<)5& zn1;+cq^II;?o=F_Q*I}ixn+zu4rYE+4(4DKxXLk$FX1UJg2itT#t3Zd`;2;aPt@wu zpXCS`ZQ_b&e}{^!@OH0mHq{$e?kSL#y<@~t&FcoZ2NJ+{jC*e#-0v7CvKT*%lWibg z$~3&&yU|7;&OZk?^P;6sgSc6R@JMhov;|7Cau8Hasx0d^5hQn6Y~+0S{*|J67uW-g z!x)pYP)S~JnkAIPP&p!T>(r>t9IGf?oSli4Q<~#k*#(u(ft>ZVBO+*X)X{ZU;y6+b z-;#_k@&zujB2Hkghb5^V-gzgxUHD*@p+bs%TS}L}B1hYLVQuSXYg;d&ZOJOx-$L8m z6M<`L8<~{bK-)qWi`}8Nh0jKAqHR=YtEG2aajiJP^`(EYD4ozYw)Dika#k-Y7+<5p z!#R#*(V|}yVg#g*{k@OJ@es`g*e7OJ*^=7x8VQ6SK=RO zS-_W17NIYnEa1y0sGomt0z?1pM9|_MR-0N>kz@>V$QamU3?w=L*Cr(K2^XuUCWW|z z&)exMAM1@iBsWd?B1|c6W{F&w$3hdJlfHH7aK$HC>DN{w+htZ;jm`Ypr)be zAp@GIO6Rx`nq63vwk%b0%-w=D+cKqPuGdNVJpw z^W?G|m&4+()BfdUIi2}$pscJMG9=(-x#TaU_;{YdNKf1_U5UG;t&66uE2wQ@w*vc8 zEtJx1p%fvEd^w$bsfJoL)TWcZ`1&s`9qY9$dumxK*>YmhmJ^4!F!3$KBh3d!*}R;N z85b;$Jb)(i)nzHzQE@t>V1 ztT&vu>{740`gM4oM+Ut;a)d4(;$WWy(%si> z_V@O7NH{%A%E7@wk0xjb@vFOgu={9df0rC{2XU_Vc=z%CLGLjMaTf`w^Z4;zx4YkC zPf~kv<`);TAsJFAvAaow@Jlfr7@EGLDI=yL*f|okt80jz;(K-fnMaj}h}|uhV(N(0bfCc(k|E+kgC+jlp=n+u{G)dA!S5 z`)Ie*Ie6UN=`tzrJPt5;uWOW|%dkFp#QO9eKi=)_JwD*FKVX#XGVn}VYzW4xT`sFV z{+nU-m=VPkb7ybAySvMz!$@PpvvGI!821>Ro$jLprfiS8j1`@oU1koCJDr{GqrFGn zM@&ukJ9`~Qz`@?mqeo1Ax{r4m5p4AR-5sXItm%G-k%6@I&(B}Iee}%mT+*Ai)U^v}3l2c&0n}?actMo+_4% z`#ww9TSYH>P0`C*C^}e+ARVlkLW?yEqs2Om%U@xJ6AE@*EP)c32d~9CdCAtvct&u0 z@yn>w-IzCW`Z4S?`muS->Bq>)=(oS?;n~Zgk83dMNwKAkXHWvffdjzjP}`b8DJ=FJ z7(Tb!*0e~muIs??IoGzPABv4TE-gM6+xGNA^3-Ap=zfMM+)kOAw&!%qRJ5+sEmO~S zTqJYV>_A7CgVnrbeMH_0KV)kHk#}K#pWtyOm-BzhUT2mlKo8Dbi?u`6KTa+#O2}r+ z9zLB;`(nW{D(4?2Y@tw%`_t8%vOhihaP+oupN-f&Y4o2IeclpI`hF@`Pl~rKwmO`# z)nJ4D^|o2GPl~~0a?zAamuWd)Ovf|G_5FOw$2wxXaaW9QSn$mj468t$vqH4@~R(%$ZfPV0o$LuZtuj=fz#28#m-f{HJqYsrp%kBcma>^zb!v^A`T4Zwc zM-^Q7(qK4jGZgpvT1(gccQCf(_QzNv7Z2Lv6T}bp9`QRs6cV=z|^juiliO!)C)!44c&RQU4NX&^g0D zmGh&&wTi!=G)Bx=*=zBu#l6Jen%Y4AZqkvAdrN+`-pIOX5ZG|KeCOrxIPr@1$z}gD z({XXRpGM(zIhuSa|G#oI3t+-5xtei2A)Pte!mn+MlDYV0@%0I_!1wPF4>KnM~`W7Glxd|lqq?A~(ty(JmGh1epVOXhC9vk9&k!IdVs;%BOt zg4`-e?hJhG#;QXRjRe#TNQj9ALm5@yzH3UEC?j z!54Q@K;nAw=P`F%IaG;FzmQr?U2EM|G^hN-)b=}Daz7ABr6vR{cpI32C1nE`2IW2e z$mfDDCB+)=I#m|y*tX3EY6<(b1;*`Ff8VDt_^RJqzDPko?;CG`(A7eGKK@cpN!@J9 zAAfHZe><^FbHz+^1>-&Z3lE*ZZ^E6-#S`ULmC|Y}SsfP3d)Cgv3;th$!1Gy>ZDP>$*gC6YPlwUnpBd8f1uJ-3o zfgkpk-wL)tIT_ZZ&+%)hQZ490G3%%5VqQ)azbIz?U%58L?D|`Mb~*Fua%Ry7gWsQ3qYoEJY?*tbxPD~tK^*NEd9k~C;F8N04C&i$c0>;=v zEoZ#-+qJ|@+`uPrvy0o1-mu1^m}vwB>`t@$R6EPEM^N1W+OfseW6LmY3oZDTTlW2Q z6!RD%qRq(vf~3D7Tt}<2SA(~@7<3jXzx7fugwDU{LNK)U3z8vLe*c*ZKNLOwP|ZG0 zSX2ybc~f1{K7}v_9e+p;+`mt<;2Ho6c{H_)*ak;%&#SS-jh&KD>5GnyFA`A1--kiP z^%rOVK1*7xjsAl68?I;Xayk1OtY-h+7PJ46YuPvDXFH<)shZBjI#%D#%k=)O?QO1? zGx%_oCVa`i9O-%aAEuK_8lLzg4YVuvq-?M+`s-l`&-lSV5>XOrE}jn`dccKEzwLi2 zUzD?%bKUVM_Jykv7wb55_wo20`_D++dklYJTStzBpeINNs=Ah(VBPqEt5fwijJG5% zT86QnGBq0y{SjNmDl~eBpPz7JSvea2nwqG=g$FC@dr2_vA17mGtIuaoXS2y!)dzPO zM4(k%ImqbPn2*?i0OCrFD{+7a?(ckDdK{U)8Gm5@JTrd|X{7pWumStu8T;Rm#@ z^b>+5aMGC>^r9S}mCt9dtM?z~&xhrBUd>mH3mC;7;(~*{;9|Cv$PYWk#V;w@nj;GG zqL}5ZB?WmRw2iAYj~RHh1bkg7(|L!i3G!RBFg9=Cd|ezH0m~Uw!50I=!#1=*UIyp% zE-$M2Q%|KYCo{@w*<-HKOLuw3DP-^XB^m5*_LtmH4;s^t>~AJCKJC1@sLni%Ue316 zk3P&mpjz;606C};==1*wGzY*Hg{yA16h-R{&wlanVKK17VBWROq41ttE}2`W^1Y;v z{|xyipzG&zlDt`0l2WQaWHP|pfIw_?z>ag znE%yN#K`Y!@rUpydt(L8(=LykF$i;LUA^57e^hL`3<2nbBp^t_!smBl-FE-^JasJh3=`>_9f zX!ISorfO%7k9}jI59%%DcXRs^VaBb>aKFzP$U@oTEllw5iUxU94}hGAzUD$Il+$}t zQq%ujO#kXI;G8e>-6^`857j{kTyzFeIvWKk_t>-%rjuZ076ak_sdp=~>~}{XQ9gc%S$n5=5Dt z@fwzcqdQmpPk;7m^237pasG4W<7cmQTE#~cp4+;kgK~KM(R&OP5g)Ax9dr#=sk76M zdV=}G+iD~ZfWBN@%qxalIc@ATF@G`6&&MLL$PTO=nj1^^sx-I3%55;>c+I3v@r;7{ zy>hDK{GmkTW_iY|necG%>QKx0Y9_uS>xek+0j_|fe367uJR~82B-Q*6;<_?GKH5N5 zAs|X4Y)lA%Le2m=(`=Xm$5k^!qygKi=|+;cQEp)q??dqhkC)>?%_@eZJ*K108obet zhqpO}wX9eTZJWg{p@SAvzUo#tteatxeyn>leDp)EpjIpYR)PTQeYi1q@3#(pF52NV z4^pnFQLmk0W1Pl<@g5SR{dYIi{h$%Q6ydx}=B4#6)Yr7<+A@fp<0Jp-; zrCRPkM`)iA1@4;M^I{_F&pB%BhbllvOqihR^DnRoPjNtXwfP{F@r&6I6EpLWP~>g%n(RFcwIol zR15HS0KD_A=@k}qys82o7ENHU)n&C*tjp#huwV=G0D!Saf}m~wnM4>{<3fss+v#s; zgS`1i9Kr>yP$y75V^nWkHX_m*b`CaXnyA-rZJwq_fJFfV)g;t5Qm^N4YN%*unUj1I z;mJ3!U9CO739DD0B~y~H74b4C3t2r9$}Y-sGcuwHU!amkik>+i(nE*K$Iz!Fp);L~}4KzJX*l)LQ8GXu4X; z>sI8?uYIFbzDl?o9fzKIpZ2W=VFUkCPG_Z;kqw$O_I;V2%94QeR28`G8#?`jJ($(r z4rK~)uQ4(+_4P?(W~X?<;T(|!LlDU~0nBU^X3=FS@`7LFfm)td*ONyu5i94!3v))) zWtBLIdTog3bxt_e)5KorTz)4(?-xNNN4fDuA*<$8lD)|d(SZj4*#t%4 zKcDjbBKGeymqzHzHTPjhXoY#u%~lfx#L*W7&GQLbTN-x%meZ^0Z)Jocmc}XTed<>y zb6?$HHalpFvMmnYUYoPmIF<0Q!vGDeClLkvhsXY>DDnJE)kjE~*uGiO;cf9>{{wgc z8^hU>Kz)3EI{;6d)_jb{Qbamnz|Iwfz%|r`F-dRFMw@kY*btYVZw&u%;nTs6K!g|iqJR5RV15`Mp&9fmpR*zD#U6gFaU@B}OE8XROaJP{ynorA1Fl!M|u;-D!V zzUa^Abie z%XBc`JP1g_#VI5(n^}hhb%7?%2C=JxME2lrG|?W0Q+uOSOy z`D$yU$*O8gqw4L~Rgn1Q}x%51?_aDnFk9kN%Ht zEt`)6?jZ0n8>Ad7hk<%>{@;@df96A=+mspL+KnOAH}l<<{(4d;aoGDKXz$Kj7zem%PjYz07fCY$Cdp8 zya-N-=LEm_OLLVg;+}h9tTmLwWjU(H>voXWqWnZKR>7cGeIy2*5* zXzqQ{EopA9yQ=G`#JtGdQxHLG=z8NfV!4ih7^K0 ztDF>u#|13@_QuT?I~n|O19>%>Lsvf0|Gb#T425*n_dQ=tsi!_MSxeXcO>}5>?P2N#*&f)kOxTTW4fDXZvuet?3R3GV(gk-4i#0&zWCev!?nfXylnCbWcKO zAb2Jp4;BcD&pCqoFcauTO(zP{FYZORM=y^Uzh0j-&iS_O|2-*QTYI)*R$W}o#go^8 zUEILoEPQ>P*=ILb*j3^RJNHBSM#Tq^sq)A8n_$+*IC}jS=16CqTB?({GsA&*};Oj1=}m44hyu?W4~k6rU*U7l%l!?w8@Yn#T8{ByXm?=c`58$qtsq~ zljEC16;HqETuJRl+clo@gpTgP-JL;APm)dP>db>Rrpg9us{ECVLS;pYh%Uu;AaI_V zMeD3+MY0n>1w59z?l&agh~L`CX>H=MFmKR4A9`wY5W6nCioI1g<|9Shv^0CsJnF4( z+p8H2k)!hTEQWhZoe-E-5!y|puxR+|?n-b?c6z?k-kMK%&!|o%_uwZN!x!cGoEM}D z56Wv%#Ydi=^4s$&<};r<&h%;0q40jLOHo5{%+4FUMN247)At{EA4hhheM2_d;Ty0p zUJ5H@vFI(;vU!_PhuXz~%ifO7*OHVuc~ya7D|9VCi;Tl$`;g#TDT9njF#EASE-Lv_ncmp-%_+xE?epPQ~*~e3H z;T`KW*kb?SJ3_}_8UyYJh1NCkg_oE7&64+lm_ySJeYUJMt9@zeEfNOz{=-vv^i0uV zD03!tG&~;+;L`IxBd*UmAqnksMdSav+dGm)Zc!_LjJ04O?d;SJ$n+5;awk~L5T4H5{wS?&jo7X8{^fG-+a)zBJYk=ZEU>F-I1H1zl4kBPEm3E1)HbTApD(Vto(c`d&#$OzTOzC zkRLhK;CUN-*jW`kB6RLyKV)-;_g0<(MtgEB{zad|P-ufcVSFTazr=@a|2(cf!}SK} z%S8Sp(<)xmU(xkHll$5P6y!_qB0&4=xUZeJK_4dcPZeK+1)*Qms~GD@1`@(YuG~+Xh(}F+v&vVP!*DMIn$ltgLvgu+$A7Hj;n5 zrf=DF{1d>?UP|e#ws}fT3HKFOy*%%LcGx}5m-}Dk^nJ-+idVKHYtlYU(U(bE*u{Mt z5`~vhlr_{6Q9O3&*HyocBD4t6@-6GvO{Emh_ND=AxWqr>{PshC{PXn3&n}nXo{!9Y zy8oqa1vS99zRfrRJit5*u2q<(CerRhHr*;H?NjsQjMq_!ZG6UP-i?0@ThC4mIFBLt zJN_|k)A}9%I=1-<_ozr??ia^$9@!SX4LCu7D^i;pnA1cT=$+FC8nRBhMLFafiVZVn z3j-4$bI0_}16dL?xe@dO?Bm} z&&LuxpOG~{)fT_3Il61zX*v~qXhIeH#E4Ns6^X)Ea2gfpcS?N(mG+C8qY}%y7H8MKM9Zij}CQ5p}>T_fv&@Fw@{z zwlJ##u|TudS0!Ix2_mfAq(QE+2={E2O zLvYd4K9Fxe8<=P2GdZm50CTs`m1y8D@xJzNm_`Owh`r_?Ds<);C?_CSKi2nX6ybK3 zL*vvam(^@O6Q9piSpac%!2K9w3%(^MUh-m$mG}$ylltXl9S$?|0aSD=20(BB`{VhNWiGXOsC}?xCPH-`HXe3;v(M!ZQcGg`(m*P{E z&ZoxJ$Fo=R@4wq$9Vh3m+x*OU1akVT;ywWU{cQP-Z0md3FtH*7N1vHp$-+;^2JNfS za7xUd{fs2c)*L*aZOJsEm0T3x=Z06}GrT~u<@BW3n5ee6jM#t9lh+tIACx!JbidbY zWPbN@zTMBsC*)&3d>;MGyu)F!^`-c`qCOWSN^686(e~qgh`ugo*ZcB(*a~vKB2Rxr z-np(5*C(QA3D|}$V?|lUid%*pE@&C6uw|@lvoLa~V;Qng^lzw~@NaH8p=%p|t8W|Y zNl+D&E=4gZa!hs^DN#bYrqqvWialjp0K&2@OH3K&g}$g9vM$d%Luy}LHgFwz>p1Y$ zEEU&NI?Fpsa!sHFiae$CSOS_-ifr~X_!)NA##H&a4Q=K$mQ%)&Y4{T`Ib+W1jybc( zj9VIuzh3vp@5_e$#Y4CWR!EY#Ne;evIG{A!yMs_Da$nW+4umdO{t;^#UJdxC4js>> zo}r}(v_#o5x%-InN_=6mjmYCi@8m9Ylo9_Zr;}%s#dz2lXK-T76}D4@6S}f_oZ`e- zQ>=;Tw2Cp6UjlsjUV>b=8+6?-S%zw^9bA{_vPkfQMu168kSPdTXpko7G|24}DHJY{ zL%dS+k}c5b#(lcv_u-dj)oMmJo#4e+wB%6+#j%4H$p7K2M@zglJ28mUe_|>*FK2Uk zW$VlSvKsX-Ob*Z6v1%2g{?cUhh%CtSnF7i;jaciJd-(mi8pm!xB@14ZeS=&zP9s;1 z6UYHX7`Pf!n2AB`1{7wJ1ami#qIx6dMK}9M&Z;GPHcKUi265oXMqEu`?Xp~>oXcyW z1v9tOfxt9`p*&9+!ckf)V8Q;g#jKG)n}r$n(=B++zwgD2l<(89M*$MFp?w1?xcJ$B z1QnFZ03pr`LrWjBGW=0ogEk^1sxqWFd~FeQ*w1T-L|V+AuPiA?YAV=i&QV&ZO6dO-E+=f zLtI^@Qb{V6N~Ka=x-H%*r8vEehV1|plpj?iPAkC0#H2Y(TmLao)>`(mMYyW%4-0p;-j$lG-!Cu8DYNDu|t$jUY5I=E5IPKJ0VTMpVv3yx0I&MqTG@;``N6$fMDpcMaf zJS53Ti5XOYzy0r4+@J#fXcG;9n|h2%GO;?FzGN{nb5NTR(vq5j(5`%Tkqw0JX76}mm>5nz%5b#HkUXaw$CeV zIiR|xb6$F#KPC=5ccm>>BS=xD>>AOL8>{Q#rCOB7(?N?fx09uzdUKFgxmKMl*mC6X zmeq+?M*fG^<9VhVtrI@&lA>haDvWDssAqoHiyh={)2okp=*+RrC~o}sw!63N%|rC_Q zE5;COnw;3K)A~beCPSw{75Spvj!`SAT)>aeImX0fAEg(CQCA znz4|}HtRIXXn-1C#!?J;jD4#=xXvep{AEX$Is=gPeU!CcXaDEN?DfTJ_T&G_FlDi$ zYgf1eWewMFA62K&1oK5(I(54-d)h>oNDy! za)Sw##LkYT6UO>&5M+2kTSpZo!kbco8i`mX8IeR|Fl~CB>~f6-a-Os<>B&X)$C|u= zeTn&}FV}7)B2FJoPfyRwKH_~~@P5TYP@G%wRbm7X#_0_L0x-S&U!TCS)?jQJnj0Cy z!m$|;(Sd9i#dI(d1M%?p{hqAHPWJC+L-@B}b_r$8hNWtPf7Bb?34zr^)Z^7aeF6OE z{@(NM_KRJF%?|O^7G?~mxbKRM4Ao76Rl#*|tcpwp^enz~sWgv2mH8HnErvz!T>(iS zEyx)HQh?i=83YM{QtI*!!wZi3+cxSzA0y|AP9a80Za&no$}t*{A(93WceL%Jx;rVS zKBk=v5M;6<6@p+DB$sNXeFEP{!tCex4vInL7Yl zK&8JMyq+VA9Rlph8O+KYD5AL>8KsCqCd2qjb|X@cO$<(q%{Od@O7w>y>?H-3A2_RJ z=*6j)=86uEQ4g^+HzMr_O}(1rthTKZ8a5y(q^qMR2jR$no%ILr)!Z09c-+bM4QpMg z77VqKQlC3!h5%iZ4S#;B1nvCfWOQlT3ql!bOVQ{7@(ziFz&t|vLh2^M*dHR6(q5E6 zL4{b$$n^Qo{1Yyidg$-W@7Q#K<9UShKGnfsI-X8&+FF?1i?GutiomAB6ZLn6S~ydy z^mHgS!Q}ijgt>EhW@u)Lub>z#T(HXX?A|42LYc zQXio!BuuO$t{#kP@D>5Fc9Dqw;F6~fYO^Mq{Pl%zfPy))^S+tSky8!QRLt? zS+VRH$$=V#)n>)Kwi85An-%lgR*pnvSBgbmVA!k4$#gtKVbC~S7}<~u-i2YU;08(5 zMVoQ@!mybrt^>$Fbx86WY)` zHZ>Yqn`gt-w5bW7dlihvf+O}D@ss+fG0z&pL6Y`Lp z--U{7I#n>(A%#66T)7y50CnBsEbAi?s%rEcL%j#qs-T*426rsMHV}3Yu9eP2^w09%z1Cnl%tG%HksZ@0(#gjk^ztwoMFE@c+$J~ z=xwev(-2{{yMNEiy;O?ELrZgY93R?!4~Z z13&O9#74O2yUcwn#&s}#-dB~ul;4Op+&6o78l#*%SE?D_?YtA6RMx+&s#)(c$Ck72 z{1mQw_Af`%(=R+9Pz))=n(pMn9)v35b8W*E0k8?Htp(;SEcN&9-d(>(#p<^b0Xx=M zdd0~5NK8y}Vl2{=i3a4&?$1j77!;l+@JD`iEefd)#fY6t>YB6#;*WC!CvHLT0&L#5L=?7f93bzR~%Wy%K#@DuBt^n-IBRGv+Ri?9)#zT#BY~7 zd;2z=gonjo;6KK{nZ5zm5k9FpKrGIEBwY6oT=)7@tXmo$b_CPO>uW9Rb{!PzSm&E@ z2PN1JB>4wVlx43ebsh+j8_0CgNTMp_^|?(Oi1K{?kAhGvG+@fGZT2DH0b zzXO{Z^yE53At^?76odez=ES`{mwdm;pp) z*rBpp6|41hcRXhNT{|+Yh*NxxQ`~kOz7ZL3-Q%s@T#CF@sy!)UeY5V;gciWhTQ~TD zbia62o~*CIskB~F?wb`wt#HPjYSzZK(uM@A6myORru2zxadX{pp*X!*LWgjOtC zy7z^^I;JYPmYSwBRVi2^ZHqbklZ)o#-M{Z1?89UU&a=g0Y3e`Qef|oouiUn3=)Sj< zDyydjetK|utA9G#gnaNxRzgAs!AHt45yy&Fu!&_NEm%g2W8CYTNf%C8e`zTs_0xa1 zCnV;RQ1-MlO30o)F{liQc$^R5+MvY!pBf&XDX6iZpLQ}jI)H-?7}LALt<)2eBOsY; zpk*RgxWD#QqLLb;F(V3blB7_{e#~A>Kel>cO8|U4 zlqQ0!&Ti|%inBDqd3K@}=Y5M5Pe;ToNfCID(K|+^b>C}#UO=(wvU|aX)Oz2^E+Qyu z7o$MXo>iocqd1BV$Nl_6SH9Uh zBGbwGu8k0AANCwFV5e^xxV3{oHt9JCRSavNje)FsG2W@PoEG^mmxix0jN-ddZNzpj_NjPdZ+L58%W} z_;sp60x^IS{5O%EcJpY!WIQ0*{5Ias{#=tk*X7SU^5=;|WGPdW=DwS3UM%Vb5a{7Or`$!oqcrVOV&_V;dIU^_XXS z|25Y8qgd~cW4-UhdVdo1enhun{$m^5WtAbH%Mbb_&r+58l>wj3nHF*Ul0p+{J0fa6 zsb+c4bcY4Ij_n6g>6ZCS+17n}XXiYh401(|&@W5wJKBe<3e1TFzrf@tGXQ>Fp24Cu zd9$h=9zM_{hn@TkWhS~H)k60kadC8&ZqSJHGpwmg& zS5u@9Z=v*6!E};mLzom26c+@6k@=9RFQN$-7T#iaa&``#;mxw)6t0F&%j`r=O+X`C zU%P!gD(MDSJ`)g`z;S@OI6y#(H zLr=p^=wvfCeBEkQHtXQ+AY}0%ikq1M$Hmvc4?(QzthgUqSE`q*PBt1|x}6u@n;XKd zIsBYqu=DDnDmpSIZ*8szxWd-z*-Wj%poUe zIh|%>s70#7n4)_p;9MC+Lfj%l=5VPJfmPMCLRv2OLeA;^*sX&t#Xhqtc6I4NC&K0} z3n;#|OM;3mm|L;+T5l!Tb)KDPFAn}6m_D$7P$VY*B)ycaeXV=1eto+0U$6EKcEWlq zzu$ECaa@}hJ1=+l9!IKoW3^*&^H{}4dr$YCM=Ec`D?fX-9jV-jRet*G%k4)oJU+*2 zzf9Hsl7#)AI|q^ahe_!1`bV+)*17FfzRfG&$av`3xIcOSi;1swu?rZny1oW4N#UPA z+rN6N?$322^Fc%!fGvK(@IW1SEv||lXIJz#jlJx{qO%N6$!oCBrw6nCNbP3dQ2f+` zeI@w%osSO>WK7jo&^IgqS7I$Fu2}B{E(bd7+FW&^jLt*M>~}@EQ*MZ3i07}KKGm^= zv;&^-n`-C$$2k7O-C=_$2LY?(EoMo;c?1^5NC;pjyh%TaSdoGp2AIjxGW{j8?_7q9(G zul-nuaHb&~#xPK8p@%~yjH4J90tOz?r2*VF+_dx10mH@CL4woB27vVMTNQxO5OaW! zaV-r%+a*>GF)-f5e!^XoA`6m*yVHf(4bxvIqvtB|8mujq;OOoZL81fKD|eJyViI1_ zyIGiTDY&=xv436E(r;tp&&c&JT*s|#ts5C1#)Dgr4ZOGspeg2?4J~gtE~fj|Qw0!# zs{g$Nz%KT9EUx=L-RkIsrU6#ix7s9%`Y+iy-c8iH8SqsvrWIU;rIbN|_{mT@Xi2Sr z0_!P*f_{)t%G{zge^NV>GwhVA3IXq`mrEAHe&q)fd*DE)*7QHrpu>^dB^1ttxBl6mwx0RSh`s zu%2TG#%w62V(c%KTL~;vbaBPwKdrLw$az%FsH%P^_wLSprn1ZgYhlm{H@0@qYU2JpLj#Y8&vZ*Q# zFNInLfRjNiFvNkVFJiwcWc+x;yjcEDM2d@3P{~&G^A~%g8{EUoH`#2=s zNyuRwp)W@DymwwIxlt=p#J6Jb(RI4dbG1mo9`QkT@Y~+&1NDFZ*m=FahVaujtl2@u zMyCBa?_wc>#}p?4w-3lgjzN6)b;yJcR(QyV**Y#dzI#knZeuX!wELo86qL-t1|qod z0>aMxX2x_!GT^vqyTE)_%|vIKz|LtmN1BFoP?N?z%tVtR$?J(Cu67X%=LYq4=;AY* z#RwKR0tX6%D(`bo$`$^86tFFFGr1~oUSo50Md8q7M%qi%0fOY~R0;(vMsAqHSA&p= z{D2#1fz&+I*t0nMsHkw~?8L+;dZMDYx;ApflZ7C@HpTx)5Pop+2=5*F(T>A>U~^gN zNIEugNOMUN2tA9hRe{JUI9*N=tNCD-0d3(e^6vI=p=-8Xn4eV50Ff+T6aDCEY5=IH z2w)(t&jmdjBI?#GC>+<78kgv%PQGuK9x*fsa@=e%Fbsxtkw`KWGZz7vtXeEo6x&g( zXe8gldzr)M0yYU=5+BPnwmHEqkurZev^nzTH|~sM1{08icWD(FwrIzrDc@hv#0~-w znS7bb>9EQ77v0q`Y*Ll>82t=7uI~;FCLT?xh7#Rmw1#>Wd%WfLP-6EKTw7_UHY_+8 zb{}O})Lch_3h_)iuHM6k29UT^a%i`I!$ODFYx!vh`F5gpt(fX08ErTq45_4=7`m|7 z{y>PHJ=^w$2yDd)AyO@*5OF&x9mvWA$vvXs#7HNKz8wi8ylJFNU%s8v|T zC%TQR7z6opRP6}0^t&fCyp9|@`ElCS2}1n9ST&K=^$D&r@s#`>Q-2MdlC zS|;<9gxM(dNJW@#T?lR%L~EL(As_Dk8wKJT7)y-AH6WK1it9$XlvrE?ZYjaI23Uh= z+)4qE;kURR^v67qp7kk&PgQfB+T4=W0k*KF&k@ply?ESYFxR&WZmkMU#%-uLFOMC{ zA2^=@9g;n?7dh{HpVrqP?P0-FtzAJNNwC$k%}D!WyF$cMTxF3RVsvX9q)((xpN>I* zTv-&C*A^F0g}fE}B_>Wc(G&m3FU9@>t|JY=poCQ0`Zf}%V)E;}9i8cCM|UBGG)(&e z-Rgsk+BOMy)?2&Z!LFDwjb`@t{-fPpebcPPD(IWLSM=yX`n_4J%bJNC8KH>GI0mJ#YyK$do5EKM~M|YH! zqsG+nZ$YkPEc!E&Pp;v8l6EVHTHR8Kd;9=&n#-Ouci5l(%iz^$q%x1GEjrs=QrV2mN)nGPEFhl zb=AD9q$!p=_l?mIF`jE}g_=js?(^~_dYKazZg;UV^jyWSaoS6q56vhLzPaS-T~2kq zg;zP7^hjg37ec+ur}Yr#@}@;-H=6uPff2U@X0TP+$-;dl3O7*_Ov_tY@YTyEg#Meo z$@mjiG_D%qErL@BJe)TwQ^vVX6fUNUeb@WSJvgr8SMYanI64wKS*`?8;P^QKSnC9X zX|fOTlEz48Jn^!cXwnyI8M3z-a1Nq(EWSv=4Sn*Px$sP_mg5a}3$iKI*Os#G;rumd z=}>6Fkb)!%k)^s{kKJEx*1H}&pTojqQUFt9f=@6e6jJr0ay*9><2j0r z$4^lhA4pSIg6I#<18+9+9=Ibl0RR@Fo9&3wz*IjsYyAtXu*P-33TwOqeyY*rhF_!^ zoo8Qtt?h8I3$NXFr#8@E=`w1Qi?xk+(~(Uq?c5)o&kFyF*t{=0dxVAEdQ}#)rqjMBdI;D9m)$GfHY8(?g>1XMaZ_r)5t7f6=os=07Lkf)&TO{Q4^&*&S0fx z8Ty5Jq^k0;Sg72>d~$<=y?bEa$?|(%w9~F^*mlnsN5(?ns_}q(z~%VU;`l@X%!3!d zZb98DPM#G8hu7NCa#rZ4xbe3Qhr~K+>F&U#S@=H}y1)cLKy(0q-FwmqoE0|uj??-9 z1(bcmtAu+>i&Nh%3~_jA#5%n718;l31g6=|Q{ziOe_d7k^IcVwk|Bn9Mn%cFW|jgJ zX8prVelG1Vx3(fP;WezbG-nEHoFC_J$eRhlGH1##E8Wk0GBiJ=Ql`T@n&A{Fgf0^d z_RrtgZR$e;$bQ3JQuiz7jzuydc$n`1mS8+Y(CqV$|5?E%wOPQca|33GpV-%L=;<4# zYs4JW#JT7yx?FTsckCYpUFhbp6BCDFVpGC?c=E@X2RnibgocoE!xq|?srbQhaj{#p zmT_l!@Y<#5r8oqBb-O@3@$hDeA$^e2OSNXx?%MA>L+^JDkXk2r>z>JTex@@3$b$|4-4X$5$ z-HHR&w+`CEo~$2Aw*_)!mX`!*7+DJ=63;gD)`p%TYcv;%Grm8d_m%A;g}Lu+wnAV1 zDb#*&E8iA^3dubW$RAL47K8=iQ#W+dLimDnC^I0G?CvF%a--7xn_(}R?y4l!?8K|2U> zsWgKS2$7_2jKcJtZ5rHY49DyyRGz;_^)_Q$+eQ*K!%%UY;=$ZjJ2+GT zBG2{ho`Jx#T3b4-V!BU*14q`e=IM0$9yXCBglFJRt*Jfg-Yj<KRSChgYf9-A%3Lq8pwjgKSma^o=9WK< zec_>dBmco_hjbmSsBmv~TvK;$LSm%kB?F&Lh5Me`sd~m*->B&ivTYrs-TA80c^~jqphL_57p_$CxhfxJtz)*_mQv zys1*o21yUc`GllaCc$xHp)n~f4ypfc_ecYB(PBw^if;Q5-Vc4^#^p|+>OTi@h7mSS zcv=>%Bb$L@6ZAQgFLXC)9CY+lN-e;l7Kr0u)vdOR3*KOLA-QNe%^4M_CuhpUR$;6- z&jM@_EgFa_Sr82u)8?WRE(m-f7s{X1RdV>dCoLVkfhS3H5ALs#RPC}5+$A`SqBTHBCj!-Do~ z!4(JqG?lu7UDt%g31bZIkXrm5KSv?`mr~At!1OFH&u0^JZa_rPeiP>-Tj^Lb+Ly}` z@{A|=54Jm*Qu0L!;asc)qGdO-?WG!n4OaU`@@pcg^D~8aN85D<0!68)Ue8MLCU0a# z)hR(S%EdpZtFg7Q>5KlX9QDVoLZ(@as%mB@?mclLE9O;XW+6wAJHU{pv#jX^!@x>v zQj~Jm*%Tgs%!wuGvJ#nPG0I5^TcrP(?@dPF=F<~4jp@`Akq-svQFJ{M?kyC-Xz z!*GCyN8zR!oqbCk$agRfjF=}%F$^3PP<}se6yX1*=j6UbCXLlOX7)7KJ?s=c)>mTI z*$z|FuNtbGkSi-5TusT(tSIOVX67cV5JXtR|FiRDWo1)*s8ZnwO{jA^{7*)8QFIjr zb?F*-U+Xg|^K>Xzbp~)2F@QbT$TO3WNz1?$V-QBRTrt|33{*OBffkJ)EQpr+%f-pu z-V!|>z}j*{FG_ak7*8i2J)p8*r^8R!dY^7?grzihkp2ELXX~O{$Gid;1JOaVj=4ZL z1kUj$FSmS~3THBV4>0ahFm(LE-0ff%mV|OsLQ$rVX(J&L&tis}=?m#2tXodykiwF> z_$f+V6b8RZBWm*ME*(p_#Pj7A@o4!=ZIWKz@@r@TeAEO*O={Z}e!2(&;qKbK$9Fg?_0Yv&?ctC~LRpTm1?eaqsEc}f^5=nuP>tI8F zdQFA$^3j>Ld(cWCsixX3?*b!VeC+MUp8j|kdlT{eIE7MiehlZ-ra}}ks1xF5+q5Dv zmz}H?MDRk;4KP0OEjp^Ta8yePSk^b0t3sA_l(dbu!-MZ&^)o685Bec@RV3sNn-i_r zqUQ?(67@<-0ZV)uB$NatKvamiG@s@Yz(wp10LE>Z<-^OP2yL~dPDLnR zKP0(X2(k|E)uG0a?uf=_@`AA;Ky_9RgOYVrs0~S8ddSaL2>ERi(JZB~*~wv48jlNs z6p|EUo!yyNWyo`gtl4w0JLpl87|lkFgssl%pBt$n#+N<-Ly$$^d%P(e(2+jw*CzE{#q`@ThWL_|argL}^)Ii7|Ot3|tJ4 z;1@2V4PE_im#$=thpp82U|WI`i%Wkw%{*T`KVOJrYHopOBoDh?D|E@`3*gI-1w>8k z9~{U`$0%q3;!Ybs9tykkNhpIdkqad_tmBtGnqUoM~mj+!z_959zp8xs1hq@ z)L+EzGCSpbrdT|5>#ag_pc&|6IpCHWgTEp=U}z&0jN`ET5w#t;Sn(nTr1W(3c86+4 zC|&SzL;r2|c^_l@JgU-CTO=F-J-H(Hdm0M9sfU&6 z%}%%38$e4VqnZS>)-&n_dO_8{TwSwVqA(d*F}neIV;Swba#3zcF$NPcbA?eTaz2vL<{ z9mAN3dVsSGH#BnGwQ20qbxkcJ;bO#gz$D{rxSZ%H(9y9fv7H7(?PUJMbz@hPCq8&u zKlQk+zS6E%Gd9&)4h{+^0ibgk92Z>qC7a@$x9y{(scvoCGIi(`hd}h{F#%Bm{2L==%K`F~iJG{B)#~|oervMT2*c65_;{l=ODZZq-RB-P%ru&=EizAxMQ4GEnmGVD^c@ ztkhHdg`nwKxz#{nr3q_Q*%GK~=MY^Ql){}=(pXoSkHVq*NSyAS=Opc@Gl+gRdWK%b ziNff=d z%*?W%T(a08BW)_HEqkLATf?ymLg{)|C6=-lrZx{Zv{1HKMXuL$j#U}FmTm>HRW6Ru zkR#cKhh*_)t~}KeX0HwvB5rD_6R*@iFt60JxFM?TKND;MkeuYhvo8^`x7|c0N!#n| z#~ZY;N$M+^>sr?IkJUE4KPc@j1^u#>0^C29mlgJ2>^x^j;rijTr+fQ58}_Noz?-}? z&QJ46xsTIuBRkN)ZBUD}arM`534B+;qsDB=u_e#|4_Ci<%2)u}z5c?-h8W)O8@SWH z1(Z!}#?G%IoR&dBFk~{Du#^aRS5^_NM+Uy(WZ;JlyRMS1h4mL<2>)` z7XrgI%N;?O*W*aimHZyqqG-q1i+gjfgq=w^j;b!b>V@qYpCtCaZl#fcRjaS_CNx3A z#i}VT#jKrR3kvL9+7=Xgt=NXL6bYcP>bIlrkR1fI(Rfg#mo^~mx7mnL+s-j0D__tn zTxTgF!Q@k%b20N&aScwK$N208Rfx)#sx+Y49zr2nZAmNG&5cl3+h_fz2ebZYJes^Q z(-83JmO%r+GezS;%yb?EmNP#?$6k1{M*u$v=S9I4zFTQvxG`)9?p!$WEkS&ELhFPg zRGgvibauJZH#n+NGZ+3K#LKq%iy8KV{&>K)(Jt4#JBs&*W5C-nDZQ!*88+rOPj&36 zSC_o>5p`!|LV-5~4&i^93(eNN9VJErui)X6aim{&3pJ0YgORd~FY;C`B5`rEXmqNu zm~Xs`(>203zp~wTaZx8plUNv`yDsg4u79Q+9t(>4hUoQZ zTs9H~V9yG09^&-0@7rmQDIf+0QTgA0IC|CRB9PTh^IR@{L zvF5wx{ck@ofaslgW2BlMUTP!R{mOj(vz;TjR7KV9U z9XVF=r_~i_%eL?$Qm@)DF?_j|9U6c~I48LMVIFjqkKd&A)e0#rf?}J9w_G*I&l@Mx z!FlneIc&X(@NJ_(Jh6MUpUpG#HK@%$Uh4Q7DAi)LC{AhHfx(Q~4C%pWrBDkoW`xW| z0|~i$sjptf6NBmacrLBWv@~?;3DNQBAalhuwtf~QN&WPR**E4j&u=?zud9R_;~jHw z8T@MJq0p_7nGJPc%#=kqD@S?3y+N;^jwX43W&m}Bj*gjb(a9M2m@K%2^%pd#>z2*$ zpcijtsl)n9AY7i!xrlM#tz+{U2hnxQHi5gjk%1-*W}Qds_1k=we`#oEY{tjmWZYG# zBa;?@vJ^%{R0p%4yf@`4yRUeQF13VS5AiAyCCGe_6P{e-!F41^!P^Zz?HA=AV;|() zhkxyZ{&f4GxDR*5IdQ-Fo~MGu2&yrW8}Ef^BQ*CONHhJqn;_p5j;Z9OZ8R!7lh!#d zU9R;tjJoFNT$^5h8EpT%47TemsAGJ~X#042URH;Pc?!y%+hCxE-&Tja6{~o;`m9^3 z|F2(s$XYEMp$a*#b>u0%YPE_qH)r@FOCDbJ!d@#Jk<{I0I_wp@X)Uv#1;XG6i8?ai zDe63^kqt5z39jGABEwId045}f*Ne!LoJZeNwmek6vyjb6n6D*mQKEbov8xM!W~%V% zs3;2va=tWiD$4X9B`>t=%tSVe$JJ$V<>|}I;?P#;c3tILSr2dG9I^^W{2|nefbGNs zHfD`TZj2&Zq9p`ZL_^&w0w~h)5UYy^L|k(RHD3_Lb#^WDMd7SQV<>n4Uwjk7bu83? zP#rxaw$}slsC5~Va%;2FX3Q6x`$E~CSO{UFhQ&7e-K4j&wT}E+#i99&rGtV*Il9#4 z%s5Iw3ieA8fJ)ooh9&@-*g!-{9d3fY%sCi|(cA-C1bkK7qa%O#ZV_nNh8+$+;-fSF z)^#<%92|KoWqfM*kb?YJ^)1u$&QyViDA-kTGvDism|QK|nu&fGgS*>fl`rTcz2wk8 zNP0Gh{bSK4x_^_moKx`!ZJYbfMAPd#&bXj5puU@WL5LF3g}|j^VDhsBf6SVY#6z2{ zn~86}$r*=dTm8V7xYQ*6!kISLD!(b^lb>Ulsq@9T)?jV~VLf%zVAC0RXc$m6Xr(K+ zZN~YOu|3x!O6wbi^wun+ylT}lh&8Ug1WG7>^5w7LVE+6|Uvu6E%U&SJjh4K0tN83# zWT|7@(_pECGpcJWa(}IDf30nQoVD$XcP_+^Ve8keNJ33vzdl5 zL~ftp!pfG^6>kW(eZ%d#y9#4l>Q!26mHw<>PBE*1HNR<-e1?U=tH#@tPk7UY)M>|o zfUv~XHoP=D&y14!ok_a^LI0HheFpFj|=-#KK>MJVqb z1YTbK0D?rz_P}QrWQ2@#6OEWyu;1|HECz8IBb3KzJVq{cJe77nhIh9Xy$xI8B9vh+ zOS%VJa~TQmbZ*=x_f_BuMF^gd@1dSBq{e%HPE(j0LRG7`+z{-)z{d`BL-L3jDC8uI z8}(?rqsqYN)f-Gii{x2kN`|_^sZY8q8zT}~LQW5#G1V8Sq4j4c@I=Z9tgTcJ^O~H5;d3at zwmjxn3?%h(T$($`is3jgepYq~`OWpUX8b;L-&5FGHDD*#;;3>(szf*jiK{(Cxuje= z9C+G}!G9Kedol7^XA;=(QVRt6Gh9eRJd=j|9_yuXYK?1Nsh=a=hIj3r1S*j+BAhqL zd=XGdPQh(VL74uKrCg9_~Hij~Kqp`-8V? zNPAC2C1XUQ1)1ZoeAvm3#RG`xT2WZWATi-meD9J$Q1lYwDhVImRba0(EqHC_Y^WIv1Oa!h#I?_{Qz$iYIgRY@Z&# zgW0-*vz^j17hRp68IWTeM+{q|ebNQ=YZ67cWX>k0z@(D6AkcR1r7vMK8o1pL7QULC zOvgj~q&vEhK2JV~O7PTN@1WAK=R($L50_EP9Q+Uu4(oZ)pUoT(FzfC{SvffbCT}QI)(w_rCe$g-+YJWq z6Hgq@T@$LA*%fb_+SlPKy9%#TE!G&X zkN2K8bhcSJC+6>U!5QIq^eyLu?R&Yi0j+2NyDX>*7JFc8DIh@tmIdo%sRW%-riU8-~apc8c4wM)!H%$I;U*>xzyTxBdVH@*HCL7EUwmk%{4hcb()LbdMmp6%{LoV zAzW4NLAbBxtFlN{wkJdq&MJ-Na=cakX@YdZbDWi-wi3&lw|jaLJw@!1Sx z5n5+nkQY8Gr3!gkjYx7ITr?&L2sUa+bpoFeCTUgpWnctPCmmJmFEd&!Ci8c!8J})mYB+49)Z}g`bXu=*6?2q)91tN1)0J-p~o1{8PZ-aa#A=WlX7%`f4pU*Vz$q&f^itg~PC zXXeB<@y1zR4EkpjVSLh83mA*NioAc8mD7wK?6M2pALIG5G)eRT$-3nH3*)~q=K2#o z$HCufb5@Jmw3rJU=1j$0RroonmmNYFRs{~lI!$$*D3FavC$wBz)92> zY!3}HJp_KkdXrCPJ30RAd|Ebp@!7;~sRd>v1CWL+b%~Wx(ndt)ikeR7D zOLj9uI(Sbe{8JMUv9q1bKF}*>*0QCx(W?_UV($#ea+TUutToq&yj+gS@$`|cg(@o@ z3u2ZauX@b3oB#2$h~=XVM1RS9JbE+2*ygI|LWfvs?&m^dYg-FD^dIQ-RE>$vO(Pdf zN44kqiW-OZXciqFXo6{gbR@CxZ5fTqf(T7q7Sz_;ujuBoZUd$015fGhhURLNHlxHV zUpkIo?c7&Zg_G{9&@o_Y>YXI`r$2r+nw;0km9K>)q*0=>TMZFEn2kq z;GCik^#IPe$WykK%}-|i!5n-(QPme`G_>|O4Mm#OfJ&U#%I+CWht&-4Rx+0$EQ`aA z1#YUsxI-3o^-}rE^;n8rGE}HzDJ{S54p{io8!j&1QiE`9*$8tn19MD~5CELB-WO5< za($Q}D&Y!^UDiFwZfh$jG5t$GDq8}!yc>Wtmmu<7W|v}JL(t8&SCd!VxbHf#p70Hc zc4QM7O5`8>gNT)g7d%<2Sy!5r&S$;B_D8ALa+l|jPAI6?*ru**j`N(~iQpK~F$KLSfY-b@C ziHlbzP3BVG_%_|*mH(58zXgx_r|S7Ap2=2BLY!hu2VfG+Xt*ku*bz4KraHc2u0cerXatrMflnou;h?+8CA%`H(N+HYLbrWs4Zv{Q8f; zp+VvhbIoXx=|yt*jS_~i`$bW+_qND^V$n)zoZoMqv?3s?B(?V)cn@xRvQhDt?XF-GyjA#S+#F{?;MYGL1t0FYh+=`g#P65ZZ!?3Jhbp(3hCpfrr6xE0 zae;>UMYElyg<X+RR;S zFuC8?+>d=e@xLs*>ZKrprPngDuA~rT zs)$m*E$aCtT$ z;~XWksCEKiUX03JH_P1-dI6s0;1sidfK&YGc>+{Rcd~&MYJCCqSb23dB57~H@_{en zY)EzO`VhuXt;1m+c)@*>O6Nn8NJ-~|AeC2(=YMJFf2a#Yvc0(e&(7cV8#BQd$6pr30*OsiNTqrU+~6INBm> z%^*qEek3UtdW#-_1#E%?49Qg!N%IrnIY8q1u#&ZHy~A$z$WN&SZHXhmkB_sF4!p(` zS?`RQWO8iL_wK7n(Ff~K5&M@;ws&6cohZ?t&P;9_jHJfH3f;gsi}ZIdF8Y|dq4mHc z;lb1rv6Bt+LhTnAp%`7q_%>LCuJjz5CaL1&=majT04PDWF+B9e$p!^THuF}&gNN8k zU-+qR3>6i*EsQAL>)PAans3wbuoZj=0hw?K1f(>^+y3NDPA$I*x4r6PBu|`ZvF5rN z%qPWc#4;)+0=yF#nH|thIHmVKD!um`Hj*^@I7_AdbL3$KvKRfqNF*U;`TQC$Q_YMa*n`M+edBpZ*DJCb>eX^IH~DyL<39pQxVP zy|s53IPr1TZnN45(o(NJncT&Oy#c8+MM}zEmy)^{YUpkPUUafMmbjFx^x_8D2L;4L zkH@VE%j-##hUqmuU}vs>oVn(B{r$K>^W$i9p2aBw!hJTha@T~VapUMyxq|_oTCf-0 z7+}5uiPM=kuiMs9-Cs5e4D|hpeou7>8aUPx6EtVHZ(}rfpO;E=bDOps16)5O z-n@?HR5wm@{jGxLiJq=Ub7mgLXzo5QmF6a&VK)Z2en`A|9nGn3oaXvl1rZ9e-%^pXP>_D4cz$vI@wjLu%$9 z`B-iKdo2v9)ge{^sRVIGCm2Kr(PA!rKfXAjzhGRG_sLtyRV|EbYV#6MclV`=8<9qP{nDBs8%DYZ3d8DQ~E zts&W;O%sZx@v9B(TiGjr6yAJYqAth4@V3Y`PMe8vq{t0z7STG9owIx-G3c$;j2qX~ zHUggo1){Y~9HOBXbsZQlfV~_;GAID2fJs~|D7a2z=U#KJ%|kICTSF(=bwla|!1Q{x z*fJl&mq;1t%QCci9TY_MqNg$zK$Ilon7!|HLKLf?2%KvuFvtlNL-dQn9nma3|=zv}% z_USz3qupc;*Pvmgqp3Hy1KYTRdc31`)=|U{sW7?r;ezRRjrU80S*IeQ0Ky=Nh}WAq zv>pZ!tT$-94z0iGm>q^+w_D%yx7L6fYm6FSNz|GQf5{juos_*LLtOTF19a;--(z~N zp?119C;#xr$loatnk7>n`M`Zu`28 z&vkG5R$ax7;nCmM>XsVnwgU3nu7s%-;RB&9>oI*-nKv=I zOw?i#sTV~8=YVgEuvV|1jwX43<~oT%*<|XN=F-_LAC44^+$P3?`o=OMx6y-xEl8uF z(fZ^!>da;LyC6U)E#{eTs3AT`*T67+uTLFkXKSTohN5(npbDrZV;d&9 zX=qUpc7&1Xl98#xK6V0cFdfFIhRf7V3 zjei(z9T{Vg0@9bG&l}}z^yW=IYa%xddSqhs#TQbqImqnNJLMMYA84!^BevsSHU_$f z;0RM-wdsGozOs;K2`()pRm7*Bc_(v8uU+<|x?Y(j0)Xx@l=*87vc8vQvo$`z8v(Cm ze;(&Jc`+!3t#Bzso7zs5D$b2|u{e}Qhzd!{8nvnIesP{O=gQX>wJ?GQ%VYM71X0Bm znw<}?GdrVb)k;(p^g@G3HL#8gVOob3P2bBN$Rd5a!POi3@!r4s0AX)8&p`O}K^@Q> z=7IL^V zZUz!i&G*7L>oYkS)tdTR)XX=B27NLaKuhE%x5=QDX zAzulYHL_)^Ny&1prCeKefV6*@k(3J4it4@C${hY)&52 zJR` zW8ZF)wdB12s!YEY$IUA`s$KRlgFcmol<$9N&tlzNrimLXo+#KX5e|z)umzefB7}>31|5v$FqL<7CGrG zgVChb-+=cA)aDfbZR3CW-ny^m$1&ek_x%m^acFUjChH#HPBw^jfEaY}pJP>}9X=%R ztbaK_j>kTZ{TSS)I06P8{3n6q_Hm&>#c^BZxZMs2NXSWMz0Ajb+CqH35uV(>%umMo zrJ8gP4q87<)LOpPn&}2g*Bx}SgEk&ZPN(DGxb>2qtC~iw%T9KgJSX0r&6d>P56wE< z|8%N0PP5Tqk?uO#r^E<9wUsRm551VOPgO{4E92nnA)=4-GY=U^xoxe3OVHk*lK2&0 z4LOd)4{>VgZH>i2Ed}$_%dNN$kZpiyNG`Z*{_V0F*i2qLG zIW7C+z1c8_jn+J>^Eo@n7;uOjR9i8^awHTgKy%di6 za}Ab%`R#2B1Gz58>}>6RP%J^;CYNE2aivzAr@UO9#J--2KaDytLE%z!1ojSC0e=v+dFyQFIy9GJuA%dwH117MOsBys_+V|(Wlcl zt;hKQD5JFZh1!cMINjrZk$18QI1+lIogU{v4RV02C}%J>{5u3Qc-v=z;Nf?TZn*#2 zJ5k$q7zgdZ(&GqW?iO@OTG5Bz2wS#w?XT8FpklQbcft5XXiQ5ow*%u;(e8y5$Ggr zYM!cpL+FQtBh#j-mrO}%KFi>3E2EpbSQOS&3Z{>hWNll_S};YY3aj*Bmi3R-Ao_#S zyrYfp)}meG1j#n5A4aRR@M!yefaT^6)Fzm zso{XSw4DESdw-|ZMsICv>gq}$tL6`lNkn?ly(PR$NiF^rOaYsG5=IAIv$jE{or<_>Qg9UtE3Ns2$0O+bmJ3@c;C`v;-QGf@l z74lE>$r`*9>L{TJ};*&9hWx%6%O2_nIfY9Bodo$ zTo4LktGBZsX)U;wN#)DQMf(2p#%MA;CnDjp{3Vmdna_MnChTC#j&K3;IZ1Mcp0+GK zJ2F9PQy5S1s`fUY*+g)CY_d{bBa2a4G9sDNbuLCom?DR1EgU2b6jlsFa!^9r6g7<~ z?oM*p>5a-yS`rh(Y`zZ~Ct(4J zREs=99#w%9hLQ*Qg<@dJakg<=V12lT1J;Awq<)b!JtR#zZd(|Fd|9Se^gKq`L`S_; zN2{Wvx&_<7d>xZgxWq96_h3pyeNCf@2rD-=_10=T0`8>HRqbHx9~eR=7&qTa?&+b3 z>akTLWY84$vGXI>mZ_^uNOq-HKJM3S@2lClLl%qv+2P76UN~LtWGg-VtEc{2 z!@t(lU+ehSy87!5{&h$Fbr=7-tNyx&f8A4m{e*x0r2e{(f8AGq{fvM8tp4f~Wa#9W z{)Aoz^e1#Pq(7mboc@H4PUuhQY1={g)j@dVAUt*ub{vE!8p4s@JZwWMmG9vMv9hHX zwYelHa7s3pqB;qR%FZ7{ZjQc($I9uhFV&3GtnvJ-5yp7NMiib5&U!T&4W>iTkJ0k( zuYIjNwW8Sl`#)aqzk2y{@9*0OJFlPZK36(l)q62jW*<`g?%L1ylGV5W+pm6az4x=N z{&erRYT)ZHI$H<0Pzg| z6EY6l7`r!YX%Toj{n)hsfZewHfVHCcpq=e}Uv1O-GYr&?ciB?lW8+qPkuzn_g~J91 z8MO+r)r|sV+ZG=qEj5G)1?#LWM*JhpPJfTVr>XvTXQKYA=KquF>{OnQ+Nglv^6?lx z6H=;Oxqp6K=<5WqleES82iRMhlbIV_10G`>*%j`IR)Iq16qsZaPk^uJ@b`zNJ>#t( zKL}j`5eGW^XX8=%0u&hUl+Uj;{ z_;^oDS2#-X-vC%Z2sq18rgJv4A&n9HiA>$ds(2^?Dho$_YJ^W6T-CLQj9^6sb=!&2B`I*K!#c6fKX~G-w$Qz51XYc-I?{-(+G!6RJzn9OE3{IEFK?W#h4ZzOU7hyu zziU@F*fB1YDs=(Hb~iTX=wUc8XmiIxZtcvqSRBHseYVCGBf|1JCEQd|^`V^m_{?z^ z?1p872t>Sq+q+6UN0oR4igABVowf_McUhACifuBm7 zhi=_s9d{#$sTjQBIB$=Iybly=w=mI9LuEs^T~Du$f~$gc3Q{11(k5?P>-Ox!e1Z=5 zdQUqVOe6y-264h)tPzgs(c66RJ|8BRJ=Lyo;Tvk3R=M(dOP>S5))lx$^<>;H)kcZ+ z;b?`zQbbmDrWqn<)a1C*=75*+!f@yI{MLXz4^yKl5l;Y8Ps~HJl!1%eIMt{K{6-d9 zJhdttppjF$9B&8di=P5`J}zk=UCAJjQ1f7&85bV)QPIb@BV{IDLFpAcS9AB)>xbUf ztVa8zwmS6GW+usEeQ|T8NvjJo_aADyDULKm6dMW;;`PJ}p>A3pBQhHdEh96mim6a? z8RPPxHHw3Ar`fMBx z=)1{>tY}<=x~YL0_B6;$WjW=r@-AQ(QL$*S8*VPlMj`rw+(<|me)|i_bma(7JrSOB zZaGcE=O+pDGG-@Quh$+U8m-qK=dxyb5v7{em`y+yt<(9nawUm`6<4$!v2fpJTppie zyDnHV-{$=xTFVd@x5++~{n1!|;3sSI4;TQoIph=7`anbH*o%sDiz5uAV`2MBgK>+J z2Gk&(lHE>LUSFyUIL`Ha&al|-14Sy9dzP#L>mO9tFa7%a*g$u6OT(Z#Hl>1Q1`&yD zfc=iH%BRv?BA|PZ7&qL_ViCX4Q-pb6wsfpalJx#o76$aJf7S~8IGyaGSa=|IOY6&bd#p8Lh4^)Vv-}KTgVNWNW}W&{;@<68iSw6HWOzVGc*I zPYNIw296mr>q4I6!vH7wWm&y8z!)M9Hn>=16#yRv&;X!W@&xf@ka{e*36v-F1hhNRU;xfn#OKyxwTD!Ap zzPX4ZjC(=em`|wSy7Ax{{1gPjKt4ij>^4_=E#dse{?_aPns|rKN7U7~sN03JVtBl3 zJDeyWzf#4Rb)Bum;G^&?c|8|U$j;q@E(=|35d372f#mQm#l966ngpBnyJ6-oQXS*; zU=$D~cZYw`WRd&f2w*up4=NRGQ4C(ZDn$N?su0{4Ztj5!+g0Ko(#K++o+`#HVuBKZ z5@Lc{CxjQ}(uRq-BxEXBtg*4Qg@1Vb=VGfN7ZR_b^GS0Sn{`|GK2r2|TVHDYsyw+b z06+ncN9#uIHrA^Ehp9I?9)ojS70%fb>UCdS@tzWl%DK)SO{)G3`*t<_KH2jb*}^%a#b_j5Yl_f~Gp~B&~PvD~cLe zAb!8|2-_Ss%Dm#{jk|%oc`d%Dz-gPx?3?sYe@@6x68)6%<=3+Y*Q;+4C+m(*=;TD) z5)%h{3Wagny`pcUX(($P3cmb;`TZHV$J6uUC^)lo)=Mx&?=CH5*FX<4)nfQuFe#c4 zpgIcKZXFDL#k4sY&5H83=?p!-?m!ByANTD6T~)X%Od#?3-rc+FcPp_^(R)7Z*MtHk z-u%#nNQ(Nsqjr2+`^vTeD>*;S~vIVq3>rCf{K+6pGbq>Y@cfUds=&uOvKW2n> z!|~{tLtl$+ffhq3P31E1*E)HXs%;BYn+G~IvlNK61n9LeSkU-=mmf~fsDl&ZBCby^ ztRCSg2N)0`VOq5=fuGmg#gAC=oYG?8N9Jo04AHy(to4y|CVTK8 zQ(&(Evw&gYibRXd6^yiky&cvnWcAm+*}-CBLc^|k=WI%z2J>CpXhv=}=YY!u`!v)H zi{ZD}1sG@J#OD73dZb!s(w&;5!Z;O%5H73kJ58i}!berr+ayrHm93k-wbj*p{bqX+=5Qu2hdEL=)vL7X6=^PBNEL8ujZ&uaSQVlBxaU{v zKG%`bfw6iYgK9tDTLt}hFH)HlDT^F{$i z^6R(xEdPRbU$yjw^woG6`4XpY*+UfQ^w#+PA9QCN-P0zw$lrQT`{&$=GpyHZu|AlM z&i-gv->Jp=zs~!^+4&y>@$c{W08gac{Of(C=LErepy1bj`c6I$v){dzuOl3;TUOjR zv#j)fz7r5&ZEf992Tq=?m%|e1=Uyd&Qj=yr0)l(8QWl?BX|1i@4cVfM5NMcS2{n{mt^bs6arbB4)%yKNS3g&F)%N7W zjl6+)RA{I9B;?LFm5`u%O3YRD^{*;W2vHf&N~kr|HMu}2728GT`kQ~(Ccx~cYM$l6J9~NlYoBbJ9#fJ zv<=X}KMB&w{gbx&+UlL^_Qc3!`+5f{vC9XLs%<&o8Z`2eQuU?zNXfEVx-0b3IRe*y z(i_vCJja~Tl$R-28dPZPDNWENmRG`(LF+XuACeL=qp;ETDM1Ol*=K&vPmWGM-@n5* z`F9i4>ixW?wgjK5oRzk!8s1ekc{{9015$GlpO4gvypGlp4}8qPY_#iJh}d^l*Vj0) zS*3qF5Ne4=ze{f|;aWC?2K(_!wQS6j1p9<>F(>yru5|-OdfI0`UN$&Sh*^V8x5GEQ zC`>&)fBva=x3~EnSbfe;HGaN#Z}q-7i&$e7-Qh;>{`%cjUGu)Kxt@}qJ8+_KUU~i? zg`#yXjvv6Icc-0}z=&8S1W=l=i%VdKLHd&)fZzl<^{lGX(8D&bZ@dET`eJaIa;`hD zxiim!jnoxOII|%*U-!($w`;1+#l&%dnFy()8T`&|o7BSm4y^FEY&~|0amkKYbiLrfO!nEq1)cr`mFuBQ2jAYpHtc zu{8FGb>md{I{qDSu6H-Wxlau^=Q!;8i&U#Qm1_MP&$ZU@kgI_#RJ@t9ux4D2BuJxa zfrCzeXZbDUK^hLH*7wECA}%aH#ZEHULSeas7Sx?c?SF@rDNeMx?ykLhHJXv+Pn?dbweW__U=e{HhjOq z(eVD@ZGM`|1K|C9HtLT@|3>Fx@~VULWkaC*u|khI62lnwV={GPrcYt}6ToN>RoQ>g z-!b%eTz5qymTb%pn&Z=;fBsObYsg607U>zH%jo)Q{*zio88!^oew;d@Ygb25le#{( zRC+ra=Gl*0Zt{z~Kjs%4y9dARy*^O?_m7>|I(s?ZCjYGM-()9L_u)fb&(ybl*oK?_ z7Y4|Dq9OLnY;4WT# z@-%`$M9%-`c|Lrwv(+(8+eT7Q<=(d@#t1!g&6Z$Qj03VTs|W#nMC4l`e)Nh;BV{RhTKQ@!-j$Ej4{U zs<~&yOG))k^fH)FH1-9j)JqGpMm98s3&DI*#S(munMKmT z)XvLBf*M7JjvU+dD3K6X&!g7dlP8LkKY!u~(Hv?vf3%Rj1R)grYX@3F|D*7hBql5>QI`sE;WXV0c6GAIPky{DSkn*<_DMg*V0JG_(XtNxqVI z)Esk8035F``m=z(^T@s7w#A1F+9D`vuGeDa1fkjbVadM?=|9lIZNb|K(8+|^;a2;m zlOaVA4Yny+^k{PVuyz4Yvks&MJD2(Tz${T_5GmtT=rHk6W4Q7sCaGDj?NnXSb9H6G z$+|Mv(#)4-f6CUF0Fi~69vb`q08mQ-0u%!j000080Gwb{TK9@4>4O0P04)Om01W^D z00000000000HlEc0001OVQy(=Wpi{cbZ>2JP)h*<6ay3h000O8oM2R1b>FnJ(A@w4 zRc!?T2LJ#70000000000q=Bvh003}uZ)b90ZBR=E1^@s600IC40B`^R0Hfak00015 CNhDVQ literal 57096 zcmV)1K+V5UO9KQH000080GC)rTK9@4>4X6Q04)Om01W^D0BvDzX=Y_}bS`vnZES5) zL5|xn47}$R3*QxN+FtvMo>~+ESE6j966GbOChqG?*{PE(dYu^#I75a~&XE$Hf1@ZB ze);+`oQ|)=>@wD=gl<=*bw0t>yrLOZbf8KjXX|Ho&srC~3xPVh^vYY_p6pqc$&SHe zm#g*H)o#l?p&j#CEEt-d$qw;9zrRpR0|XQR000O8msmww8fJT)uG|0s6Kw?m2LJ#7 zaB^>Fa$#-ky=iw_H?k=DJ->qKwfcyPMMtCt53+sR&d|sAI!RyK=}F704<&8cv?WsE z;E1+-fBUN{Oa-7YY*KQ%`}J9;9T6KS)PzEzPyoLEx-);%{NrLec|9GTfAPf^fB1GZ z8y=lCKTgJHqj58wKAw)|Z_bAaYq+;*k6za72*VRF*>_(i94)|{UY zJJ0Z6D1ADEf1WqTi|K6izUf}x?~KOtt#K>^36cnma%Nzr- zlN804rXM*Va^cDHMRRuA6=ikO`SPL0$l!B=JtGQzOAhw>(N8{mqGR3-mS6x!37w3R40QhDye&0-IIjaYjL$q}od!UU>IsQQ( ziKkjd%EbHPL3mgB){#UWq^w+O8X)is5B$PMZh__b;RZ9}-<#+1 z%ScqQ{J@zDi=IcNEU6m2+sag{tD3{~!1qb;MaXK0a@uIybCXqwoj}ec1&^}gYUU8 zC3(>KAk6iehuv)&0e0YbnzLDxseak%bv{57_|LM9c~Q-v$%j>hTlTPgsfTmImXcv$ zgqYy{xyA@w^tpnbxLpc0DXU8#s||Av*Iod<$Mdsgc4#EM>Ucy1jls?#+eaYY1m2>^W_$lv~$Xfn#-YPpf@iA=oewQQJx*W=9NpLnXZ-S+AilH&4w~Ju$)HUWu&O z3a~*81Ol!=R$lzhnJ?Jz$gPQ^C3f-9A~>SGVrRB-b&|5%zMs0fh4$QhwepHE&)8_* zJhgs0DK4D~aPyQqAZo1#RNAd;L`y|2J%i@+A|o{eoq~15A*BVQWzUKa9pJNucNB(_2{v27wiX(Bo3*CB;yIY8ydh!NsC*49?4f!W&S( zTPc7<=*S!WzHjD5@hXI4FuD#ql)JJ`4Oe&!cU-JoAk{5+FKI~;h1N zFg>7|C0*Sr?pw30y5YUSmV^i2UkHw>k99qBcoSRU-LJ9!e zZ6ntcbRy3^fb+YP$*<$p1CoeU(PUF4SZ;)d{P&$M6;mh>|LUsP)9c7287|{8HnX*5eh^C2=My$Gm*^qnmlnsK$A*~)s?Z%p_d2Q%?%D1^%wH|-T&-RI5ua5M(T_~#4I`Rj42 zddlA;r{b${DG!4~n$ha~Ed_aDAd8c}Pti(F7j&aympR`nMdhk4SPU-^YbdI`A7*Pm zoBVoRg4KIw*DX~5TPaeaWmP}AAWxCFRfQP#Ob%fb-Qnbk# zNm^DMmt{c~2wW>v9Rp1Xwj@)*t;@+)$f={`C)(p6oXm7^A}*CgFH)9JRCNVO325nT z36^wMKtG*bX<1Rlj6gyePGn+1@%H_(UfrHZtJ~C2JT8sSV^S?a)?dRX9k0Y6U8=a* zYVG)bIE8Jp`^q`g0N4Oe`n}Pb6ZZ9vUElw4nV|uoL{u-R zzRv*^?$~#pCn{lAQbiQ=J0)hTCs|BD|9LIDr~r^k9rdWvu*}%V-0Jk+5h*p;{PzSx z20wxB1gRwo1lRGfE7J}94^*L+c%Y&JO_sr5LLUeiri_0y)KpU1=L@<&?uPsUyB zhd^XH>hhjer>TM@>ZwGMso(3Y&*)@`pi;M<=drW~A%|1J*7}1^urqPU#TW*E+*mN$ z90q0Sh{y&BL78{^wh*Fj_{ zKgsD>&eB;~o2(Z8sTZ2WHc`WP++4QkBY`+(>DMC>nqn_c%X&HXYz*?i;^7U8paHdD zXtQRUD~)45Lp!7tpD#~0@^;Fr}F;G`Tj(rOPq%vM^FiKnNLiiC#s>b zmXyeBIf;w>Q(WW^k1zm>KNtEZWJMqFh%D=7p}SFqE`!B@_ZH}E zt8<#s%rrCGCet$wCHBB~J_D+p@(M;12NDd&ZDJp{3t0-&2>eAMoyDz4^a}@LJ1BualVDUKi!zU7p(ganB4V>rI%?k0MWA;foTl9Nu|E zuIf4rEN8Lnz>&>MlNlMKF7W^Avuq{Eikz-oR-`32mPqC=CI{P7e1AQ!P>+lTLI zMJp2qD6PwZ<31D&ihraS;8GY&3W2FUX=kq98%A&uEaJ#2@+%LOVZp~Bj;a3){fuet z0))HJss$DoN)dqW#(|H)>I!wp$ABr?`AOELT|If`In?ugcg)-f;r&Fw?@R7oaDo;vb&QCTC#$ zVNS*v#bi9oTZ-?8<6{>yT4`N(6zL?zsW0tGRX>+qFSKYGpco@8wb;ojV+QTwk5rVp zSa@A5f`yzqBWi^{k}ubJI(ydO4HTnI6wqlG{)>tPe^5fRCj!{_rwY!DBT^p_DZ*#u z4kF`1h(+)Hyy6dTW8TA9b;*ii-(IF*wwp| zM*>qB@Kp#RkW2(jxYCdDxrI>Z7NE)awY>!>+AusX9Oe!W1}+iDb3ph*FaF5Qt+GTXWN`gPPr zXuK>IB}Ub69YqmPLQ4~4CloS6j)^}0j(Pb$t|U-_Qh7k*?aM$Lih;|Z$$T9JO6$*! zsZUvZZa{hFH>EtW?yRUfInAk1oOy-f$XUu7skd&b7SA|{w<+A}yrmm$aO!zWfkkg) zRa_0ptBJQd2xs6fEZl{KD+*d7sytQs)JBKLfSSPXtfDvHiR_IQ00&Y}C7Qp@`$Fs# zf32|)H!{}PC58we4rjKb^T2Mu>1aazUU9S;96@ijIjmdfwuns!J%10^6uWKXwYLoY zp1PT?u3-~Y0X32iz24}LyB!Zb{C?+4YMKo-<%I>+ zI&O}$FxHB6gn3~rD?l(*W4WYuAvl*NhV$t1biXZL&SMUXoCjAH>pQWx@lBI)r-xJBxw`e* z#c^yMdsf1a@W#CzB)%bZ|2vPLrf82_xzMQkijp|b0DXLd=V^YNOfCq&3^2U!2wCv^ zGEjgh-EYGIDtOle#y1rDYH}@_b6?rwdzoy5^+niQNrb&D*L!7dzgQf#5Ml3ML4-9U zf2C9U?zFeL8$XnY}7J>F?hSIi{4ZUbyW77?v>v`P}mLKl&%=tbat=pX)5^S>q70HjWWLzwFB zJ3qJ*kLoreiGZ&r4(}q&^o4$@+xz0n75#p5J!Y*BLq+5=A;biixF(T)LChrrLG5YUNUQwY8Fr4VCrT~g>>n;3eva*$Xm$l(IEB1f1C--*(! zgQ!JT5UO`j5=JTmCed0X}*KXCF?Pt4vEdygPIj?;S$qy zXT~uOx35$t;>;u}Q)FOfUZ4^5N8Ww%Q7yYdJ`G%ou74rD%~4^U+#>e*p2O6&fKSz& z60MXI9rT-DfAesen8#6`CQKx4X~QsfD~&F{Z8c{&eA?!__`)=OhtozqviZ&ub4d;O zKxBTv67yH8#Pxji`ptX|nO(cQ2%(!2+WG?H-n54HDJ{hnC8&i`6eEvtt~KgFA)6%?NNtUI!q6BM)qq+9J z%xt8RPgt79)*vGlr(Mw>df>RR9*;SoCD zSND$3QT8DL8pVKYZiZb4Dy7uNoz(fKu01T}6wn=`BmFC!s#B#2D0I%sK}jFGGRPKA z<%EZK+~8CqeK|UBo{i2&bG<$rHPi0iX7+MudkdQ{=dI2!-pSJRb=Ij|LJ!SbtNy}u#nc``@x!5A>@E03L#UVnOhVC3{O~Yx}(A?9vHj`_2V?*vUy|Rql zim&DN4-r$moU@)Z&aoUT2%K(So{k(`*%s8V{y!;5;8rYRt}?d`^b)|aSZ2~MDbDF%^kt7c3cj#uSw zgV9rgfVdkULHsM53{oO zKB6agZ3tDp7FK;QP`=-=RdYf=0^umrn9+MVboHz%UhfQH48I$75FhFDIJWwEKE?1X zi1;RSbthAVq>friV(7+#l^{UGHG@icN)q;Mk{9SlYDAYviLCYd{1sD> z9c=k3PW!oPY^Sa3yWAx`@5p4*kT>z2clL~3Jir5Em;}wRPj!&B6_u!81%Lw+TO=!V zFSDjeJZVwKf%bSNxD(F^&b9+G#ltdW+BC}kCYRs}Cr^;`Nni-5`K5$072}|xOCqso zxcU+CR%ToE93S(AQajjH9sB-`-()4TJ+$XHlI!?Wi}*_NsB}5_kK3VTEVn`&lg@1JeN}%jdDo8sT)RSJCy0$TiU&~Q zis1-!fVU!KnCh!IEGsFw3V;W;%qJ;jV5K21+SdS^LgyJ81z%d*3wIAr_MH1*y+?|c zrF+KIQ}WU}b;;hASAgp6Xnv5f(?&}K9R|t0!(El*Qo{szxVQ$Sy<)prME$wX6~@3F zd&1^=r6dvJxTWP!bfpEm#1AYtubrCt(2d~Z zI2<+^avBp?l3#+byCZxlxXGLP`C#snm7y1a4=RB#({6@z2tEM>e)ZS$R~$gf<1wF^ z^+~LxJ+9PwpUZgp$t9~f&P3dPu`bxsgY2UaAS%^;1ff#td{Z5zoiQld6#B+FkVLJL zud={qlNMdIDOJeby%SD|!6a5S7gf$j)qF{CBYZIhTjz#lY~Sh(^jeS7Sz=b099tOZ zcCXddPkU7;#GWOa+~m1%bbc`b^#ENSHz#;W`P1>dnU05NGximWe|*+?=zWKAeKs05 z!)Xi#Pe2P`u$aK`?>R6yhGH=8Yh0)|DqS-m@(*B_@kKP-)8pxA{^q=ykB+}MpPVet zn$C;)$!%A9o0CZ_Jp~1)hyK*G8s?|czyAF1E+9$WTZDne%jC61SVhaShm(cr7=wox zTT!EcU8i%xn{3<9y1)a`vmi(XIC1gqO*s;EKBh%o-QB|QFkN~WJF>oF73il!D!5IU zCh6{2a>&M!Pc??IF~*V7>-Okx8aDm3;RsR($J|6b08q3iM_&pTgM_Dmpl1V){Wb}O zV{`&)f%O7ly$Be16@j0q!vy1C1!lMzEop$$p%eLJ`Jy>HwRL?2uR^9osd&J>*e;3g z%DA-MY7%j?N}&32goF8{l7vc_&)u>*n30v#3fq@PRK4~v4vXofknv`LN>!^&sW{yT zXVC&G%!?&sdVOn|!-iq974(zE%)Z)zlM`w>&Q@c+M@?MB>#@grgWe#?hX!7q4eYzR z>U77h{;hHw@~sOD*3!8a4)n_SH=D4iG<6fS}22E};7>{9G=my)R2IjuNx+jy6 z-H#WS1(n7=-MICvVl;9}Hjd30y4W7y2p0KZ1|CJD!83KEteza#K+b%frNpeL|FR0Qy(9u_6~rFwMT_}e_@3=ILq+l8%e zP>~`Ti-JQi^tG!#S2iJ*n5&Fc&7K5T*9xKb@`&K)e3MU^kuR!(U{8fhflQ|F_XK!= zwapP5_COI+!B1_+7+I44Zq8t3y4q0VN{@bq({XOloPLF+TFUBPcCA|#EzJ;6Ev@EP z_Ss{7wm{bm4AnF{9wKO~S)mptr3JfFW~K$-Q>Led0FvgYg(TXTs0eJvSoM4x(aRdE zo@66RO~gKW`94B}7&l40M#BgDS~IF~QGI1jn3Kwx)c1P)g-6Z;wzIa8ZxxANHl!jW z*W#hXzF^oJxo>+bz<&6VujqREtLQ@sC!?J@hs=;xws_3H7+}sYl?)kxj9W^b9MJp9=W07 zS*!}2kQ+Htu+EkxxP~e95PL0{lQk;brZ`hjrI-f5f7Egc+$pf}Je*W?PhaDF`e=#|O%%{%&r(9g!c0vZsAC*6yZg)=#R{%IC z(L98#6-#`Kj)IuAAnnV6CY~ByPGf_mlIBywc5oQok0?`yrMu|-vP8o3h9aeZq>~!3 znQ%t_5&j`u0~|ds2;JNclMZn6=n=#}hcg0W`(0_fBves?6`z&?yB^23)a(UJfqgB3 zaywGIMQ!LZ7+0d~I`FBGEicRrn5dkc0=>YCKmD};XXig2CCV6IJ^4r5OMuH*?Jw!Q zrCzYPL>0WyM8spj2zSrjRLf^l9dxnbdT$eIyAJX#8M0cc`5OT%DI~Xf{{9_&X}867 zZM%40&v*vlvb>FV8Sa_+=!YA5!KK>aB(tJh^Y1fc7$Ke`l7GD15?P_z#)nSba~`dK zolLs)2Q8#qi$+K5szbUW0FT93)d~%N#Bxi5o2|N@i&|>l_#N)anOUQu+swl%~NIDl4tQyOb3ubeQ~N1=U7R8E3ap4`P*)s zd`5kY>9zG>pmU}qgO4W$h82EHni8pUiL$Y|JoCeOp>Cxq$--LA zlzbE?xW^ItRe-d2 zdQQUxQ1k>7YY8h|D8=B{$IMH!BEGtqv zv!=GrM&97m5l)aPoj4bD;=E2Lg5mGO6m;UeLMP7CI&r?bPN-8U*D$`3&HBK`_@7~H z$0OKXupA*Q%;SZD{weC}!8LUi5B|0Sy`DiX3iRJ#fXBm_-@LtwVw~p`!ynq~bQN2G z?0dIQnzPBTYv@6oMQ*UQ+7M>i3xS|46z5X`r&!I*3y!fDZRmYI9KUYFEPd$(+}bpg z($R_E2S+D@QB!|xf&r3--#_nRj+*l-hPdm|sU)w9MofYt@~6t@SwYX!gVUKQ@4RTS zPH60-I)Vo;)k(vtoOu54Vlp4$#dTxY|2ZFy#wW1la4FuB4r8=(FVxj33XhZ%qt zm?lnVat5U=AvedF>pmS8P?0#gl{&ViN&HYcs%7e#9kCpR*M2-JPogHcoe?ElVtQKViJ5z=yE zc?$E=)mo(s7F+3n==FRKb#RUf_ICLTH~~}DrQU5~0oIzZI*-#|8XJFUtvPnGgie;! z2_4&0mo%3;Sqhyj>D~d;$)aB@ThH2`n<;ZG~|(A0cu zP!e|;Q_rSVnbk3g&;>hF|No0a7pVi1(V>g*P|SZ0U1Sekgo?RlcH)23a)m<| z|54fX4_!#N4~b!l*7q8%b6}(Okqoi7@JI$;?tJ?9W;%H~!+*P#PnK+l?^lGjK=20q zlayGdVJ@nEzXLHpdYb|M z8=clL9IJWv#e{JMgQ~;x?cN;`U*20a;ht%9kZ`{^;}>Qvld1M}GQqn|ie$T;z1C_8 z@-{sv-``!d!cmBG{sTn(0}_7XzJ_lzXTv+JbOrj`yXwV%9Ldgl-RvBPuf(>>sqYtZ z>ig|->Mghj5;%SF%L=Fct|Q65Urw@LoT-IZGpo5NFnoE6&{pq0>5KLfnJfza z`e~;Pln#w8;15iWh8B4OUo4J~o7oID653Hn3kwSUDmvM374yVDV3pApXfFWTi-5vv zJX#?;F||JbpG7>_U6N4|b~9y83cid?>TWU#<*$Qk z|K`$f7xVhJ)QnYQSJx6clE6fvqxh`~;T8!0(H?d^x_O$2=8RMTgx(nVfPtwTWHs$z z1j*!P(BIINDosQ89^I;%qV*He?xy{(yjfT5BV1Lq=;xN#4~D?9eMOIOidW4l{`h5< zQ_+JcT0SAWAtpi6w7)V!RC>aaa;x5B!5~_2<%#sl3QpAe?TFe?*YF4gGCZDl@m+V5f_@$%svNIg@j_HDCjddexjwt!nKi#WI2pYj z%^z71Hb8ZCIlC$c#)QW=^aeBU>)Yw%;``BbhP{&GtkJvGv86^-KC0?X-s{8kPm^DR zmu!j@5DG}Zv!TKNR>%AeqyWgSB4Q<5| zfL@WzfooR~m*i^v1onCQm*Fyef~YK_3l=9TvIn%`xW4_}FORj@JxV!M5-g!~_0z|!x8Ht(zb z7yy2_{mSX2Wrt;GX;hUMt9$U+t2ICK38~%|?4YgO?vX#yU1%}1pd!6R*v3J85F;;p z&Z3iudVJQ5H&BtyJjb^#E+)U?C*B2Cx5Nb=Q_7%5cQO=A4`*u93;UR@nsI@ECNeNDb?R2x!5Y%@l@&e3wSV#svh-q+A$tYnjsM^w>GPeR~8p=~hrWx_z5$EXRM8GhHysXurK59v=>S z>njTwnpt~}3-T@)klfH}g}M_?VqR6ylKx`5KDf$6Zn4E&d&IUIEJh7{CF!#44hMr? za2G7lbx1SgB6Nu>hDO>QcDQ#dkoWNPD^Zms+9iiNqQQ+cuNwoez(!rzKt}F3u@N7SSY~UhAspFlmo05O-Tc`6Qqaz-8OZ3XUq`a%5E1wA zR>e6L4qJp5IcvQfMUxeM2=8fA9a8vz79MeN-s8UxMQ|mfQyswJAGiVWAo&0hi#grjRTq!O{Pf zlo@+guO#JC%+TZ%bw6X7{V%Wr12tXF+Ul`lgi0GhTdRf|T}lA|MXL*2rr50_ru15=s7j>OM1n8pBYY7#*4~ZdT~`%qR;X`g$a_1! zOvY?{GX3|4s9(<;Cpm+g+BxHO5=7{M^JPp3*UP#ATBEaqwtjbQ%9;qG`S#WB1=0o# zY4%4q@#BuLQ4*v3iFkq?Xo#;ov1P`HsecN)=1tov?%C|uA0{W?0om_|Fi#)DZgi1j zkHVPV(;0^`=gus-jm(2oK7kmUaBH3*#u#MIdFXPj2`s19)Aq>ucRNMG#Q(#%Ybh@7 zvo-9t-KMFbni)mJ@&W($q9_LA?Jn~7)5$qN!()HwiD3$7 zq{vp~#?dbF;VW?)**?AIZ6ZVIx5l?J9}e-V4~6wBWTio;^EK1?=(v)qMKNoQxHqsg zo~V6S7UHIgFGH3P7SO;g+u@rQ(56@o1$BC~q^I#mjU}|B4wNMHUW`gjdvLhiT;6IV@gO zWAP}71oRKN4H%No4a4%TmeWeDl(dACRye^b50Uflaq_egoG+*(j6+eug1{GtWC*j1 zRw0Iw)HBBkT(e#YdUjP4e${qw3H^*tnrG4aqLVZgVHM79iv;mA8Et`Y`KqEfx zI?ha;?9%c;YbF=NUlxsl&nOn!&GRaNqVf+gNS+kuDbfFHHFN1ziJGx;c>>{myUd&`*o2+$X&}##s-K z0OZ4CFciFbEOPjxh#9{gtos2B_VHvf-$V_yJ*uEq=jwxQiXhBua#$Px+YcsrrW&cd zZ^(hdBQD__uMyb*Oh#jl2;Vf@;#&$}F{ssSp|9$IHg>~I?`q+kdkZ0|s$Ho24?vxf z3ur>2TWZq%v{;YM;gDIxUoa7ykp!+iVTvAyhWAPXtPbCmWxCb*5d6j-q{Uo18tRLZ z&b?Yu=gix!yxa0YF%?xn$h~SY&m>ZmqKw^@bc406(-79+LsB!aglOP85loBtN#FOV zndDci-Rw%Q%RWRFhr;&BV%kjpP)rXhaut$^`g%G4r3`#|HMB^ZA7bQ=%Pnil+6TO{nB$fA9m#f8(n_=^<1eL9kNTy77ipHP} zBQu%dCDxyJGE+VNCX<tgR`#uyp08|$p8HN?i_Ky-R*|W! z=Qf<$3?{ATwz7z?X>MbZt)JU^p*p8$vUuA2TytAVSA?mmq#{Y7E40hX5lnKvG4t9X zP}Ul!!heOSFVFN9r@mft>bteZ)K|@Xz&bf0V#i-~>S2*2RU<3U^`}YBAa6K+&S^4< zMEx|`!mcEy$>>%`h}>0PHwj%d!p)GN)SZW&ZzgAF4Nbta+fWi$gKexKoo2>Q^W{aO z_Vb{r%Gn__*>lqRFwIK$1KPewlGZc8EyyF7bagloq-J6~rhjYru^Jtl_9ts-!mTsv z=>t`_c;*;b4Y8Z2Gx(>tT}=6s8d<^<;{Nz|uuJ^${>a?Vpw{`H*uJGiXof~x>S*#N zI1e2!HdTkvi?tAf=_bO+vBg~Fn8P;5QWj;3rBqL0`e>g(I=h-fL<=ukH~c^!l5qiJ ziUILhV-=b+_$9m7N}UixdrX1@hgMg(S^ZQkg{L#RZlXDn^o{=7XgL;WI@-vo7gX^| zHa3f9W5d{uAY(!pW+r)pf%h_+d^=QzC#FNCmA_(F(|oqP7d}U#;cB4BGCI*#zpD?6vf}VGpWnxeJBIJes{JW1hmIjWn1t z$Aa)X==z_tUY_X9rCdMd<*j-xGtm@YHI%y%*&C4dsy@GkzT`N(G&$Tzq>k*}$vm@~ z+C0d%=|zo9710lniOU@B_pdAD*ZyW`UF8m75u9`ZZCo*(?C)_me~VM(i*d~O&DKnu z%!1mPi`P!iTY&+M6(DtOcWJSguK&q{%WnP6gA{Ik^Pv%+%86U{c)1otc%Ru5%;vhdl%b7U;5=x5y$kacYwRSDSNxVAyG#S6LjW!?Asno zoVdoz;MB{LKR&x1!8R(G?!Vghr0*cFz^}DM%EFAzQbcfi5G>sb5$)A5uU=e11-dK1 zB{>pz5HrDy?~*~j=4%2Y?F)JU-~cy06SB&+$|zig%a9EDN~Km*SxQ#83_JrEe9D66 zVT-m^>?PLKm_JD!{jTL*n5Z$4?C7rQ!u_MBqcsf$>^pFyK>ZpiL}-+)0wX9xQp{n; zwkku={>ssZ!kwcJhropNBx2>E5eu%AG8;u z4@(p$gDO3i(zFujXTC``GJtXa`Kekyzk6+xw9NPA*j|hbkSxTE46{5*O7iE6i)N~G zOf^D(rJn(oe{+S>U{!6x2@pQ0cG4^;lu5Iq1rEO~uyCMrnpJIQ_=Q@)76r=GPU(%~ zPFZ70Yzybtt&lEf7xV{OI9MLqyc%Vx|)&ty5zDd`vIApI;)zjyR139S>?`9ZOx{qVZMTechtAy z=IY32pl=zs*wvP~zNOGs|G7-n*L55lc*PJHnsUn_UeT5Mpsrf*H#L0ooK8(ZYYk}3 z6lv>KxWQ;BAnZT*YGZEf_iFi-yj%TKZsetNBlTp@dRv&@@DDTbwt(Y;ws?p0QDoaAsx=Mh+5%ZZ>OVO#e(y&`vF zTV-XwlF$<}kK->7+REG$xeI$hdF|5u1_kd4%R{cM+(SsQ+!JC?i?1%=enW2@2^%F* zPo>S0puzeZCWtWK8_5%}`u<1?uCzyz<4V2Q%mul1uT^Rc^`t`k89MXby{%lC+L67e zcO_Xd?9@x5HQ285ux%c0g{&OY+sllO%+wFHo~Kd0#KNP6tf2q($5SsDPkAg?A5ST` zB^eQu+so!UY+wr-suhw|>_ruOLd5__)6OZFyQVyd; zabbyYwshIe*%(H@CfIEvE~Vvw340+>wa7PtuA-QN+mTk3Q$Lo|vRY34oSc?ba$-!c zSh`mUsA@OD2Fz+D=yp|H!FiejnR<=kFDFenaf zVG5Fou9{k1Hu1*eb}Q-RwhV*3sLX{~6%zV+Je)3nr23O_c8cj)C#VNm&B#VG^Y?0{ z(OWnWN)q@t{?$tg#Y1ofu_&~|T*01_R25Avl3EM!gdJU<{Y7zoGaMf`XEW8}eZts9 zUTZHQC4sjGb^TsXI$?;{DhC>R8Scj1Dl(Wq6tpgR@nWHnQZ6N@(_Hz`0F>}XWrQIFQ1K=O7AJJ z%jFu;;RL^epC0ai6RsFdI+XtB#9}R^E&9mMaH=(ZhmOxZ9nYKTcnA}oIg=?K_O#Vj zJH|;TK>eFD=v1nfdt)xmfM3Bm_l6(qYt%^>b}>djycpvM6oNnlRFg>)PTBB%TlXE` zJ93pn+fgM6MZal3(Ihx47&Xn4+g^4$p)SFaipDwFIdHM;`dQg+BLqEk{8cdC zOW@CHSalnQgmeY4$W9t_@f2cdE;kaR2sh#~;ZF8FfpZ0zE5?Bg4>}TU z8M^u*!#U)>f!uGw-Qe_izlOX0_S_}htPTs9Ry0oPum`Rq5tJe31s)`;;j)8Rs0Ly@5-Yj_!%u?^MAO9Y4g3Re$RK)YhxOY<+b$WAg?B|Fi; zj?c^qu&=L@X$A=;M}T+>N24^w7MaIQ@y8&%1*maD7)=VT`IFa{CqU+}a^Z8ce_==^ zjKpNkVHp=eQ6Jn_kiDFt1xcStZ7f7RYX+8z0{+*e3WPs-Yno19D=NsV(+bu>C_!H;)smb~hsSfW z?y94_7~NFECHo*PS$cF${4_wWs3ikq%hz$!kHx1~rKMa5EWKun7>CLeULMtn@MiX^ zswaG+YiZv-3ZQMV_NAWdBwAV9?c}s%ZV=*ZCZ$sICD>buZCtWs=F>Smy!W(qqXg#;lg5jZ}l-E{w z#WT5W2s5^1DS3L8^+jV&n>dwqLbS!V9E2Kg5!-BuO?;`5#IzkA$_*0LG-C?L@PS7t z`5elj!xbuM^l=3pEE$Hfu|E!tA92fV{=^1D1CUKlU`4I)tv6gWHA&MV*z&eGBpu`m z0~ng?SPAmhn%`u{@Qz|19IYXAPpfc-Qo}ur$p5Vk%w?Yb@;Y|vNkwL~=+8+F?#N_s zNv%FbT^Mnwn&EE8I;+=W!l{H(h)p-zfQb!@FQuwc%Q%%DwzB4g8gHa$M_rX7c`J>! z9VLfWr4EO~OVFD_EUNxCI~}iN`&IPI1$Zj~uuT*CRhfkn16nFTlpW*TZF`Ale_fdU z80O{mZBo14`gLLUIm{}MWcEKK0@f_^-zzbisF?AU`CFg#Ub!=S3V?1EQzyy2kGv}n zhce$%{UVFDJR(gA>%jI*AEL!l92a+ch<;&YqWsS;gyxsWaTPxXU%9_ul_4N4eWSGL z%Af|S<53*c$iy@rND)2XLMck{d7x8#9tigPRjj`Wm)Q^e(4Fu3jF=)kojq%C*Kb5- z*!{v0b=n;%qL_YlM*uIlf5Un806L4vD7RvZE9KsMXA5g z1@}uvL5M!ZMzSsn)!M4A5Gsa`0tX`-N`D2cf0(zTtJ=%|*uLMu_IjTxd-wNn@^O#OJrtF z_n>%NLT^f??3PA?9i(9)8?Hm4N*xFK#pkx-tmU+$eo-Q3jn&V9tWfZZB1S-+8537VU`pdV^uFewAB4F^zU0`* z4R(kEINr|Eof8-goAxi+33Zjkki%_^gqNbl?fV%g*oD!|MCR_+)tA zjOW8M^==$mR-x~zU8!~mO6X*g;lvI~@PHt9ELcLedJt8(B7;m$k}wXuRQB}X^tK~p z9kDrlUapcJvg#cXK2Y`U#Wjq=8zAAThJwJ%R?s5t-o zRiZ1ISGWnI<;Xv0BjyKEJ)_9cRxkf37$NVqB535bO(yV}o#mqp^n{l1(P)wgXSC^W z&7gUCGwR+v4gg<3puZ>&Qvg^oE^Cf67_oSRRuD%E*j$qnzCqN9ki&s$h1E)o_;E71 z2u`YO>1%qU+nPoF13b<(KIc5ZO$CJ{j+B|LN#yW4b{a#)MzwVnqu%HF{0hyDKQ`kA zq-AxS0|C|~QqNScU9nrmn|%LV8oF&=XKg!56Iv!RwirQgViiAy#Og*}!k0p|cDR!2 z3Pa22ioUnn8?hw?&Wzx4cX+dPVi1=HjxeaLf;b^19{EkZ=c}de&V)xbKtsyM$n{b2 zkM~cK$H_m52gwJ~N%Da?mP!AH76!iNGoica>}g&g59z0@O|~bo6D#Ou|DNry_t<%8~>!Rx_-XC+dgc>>cQr&ra`pwZ^~1)AX(1+r}8b#zz&w zKaqR~Vj@OGra?__-X2OJ^8myVZ>3RB{;qKW+Q{Z*xt|d~e=&!GNv3*bIv9I~j zzbEx+c(QX>>eTS%&c4*E=FQ&Tj?}H@&rW~)j?}T{(f**nEA_1TG}s;76}lc6R_)&1 zyCZZyFxq-+Dt#hv}Tced|II=5pOd1vR&ZvU>Nc{`ey z{oOmecX#$B{oB#(9NgQzw|{3KY2m)+*xlXT{X4t6*x&ZOy}kZEanD{pu!2*R`AVJ* zbBoaNfu(A*ze_z{Oq-L@@o?UN=~u!0 z17jM;_|L{YRrHt@{aqCeS<#0L-zd6npU&<)8O?d;Z0`2)^UWs!Mk@sK9JS=!%aJ1@(!mXZT8>6QnWL}X~`}l zJS5*)U(foKFl9EEFDLYQgiBfY3C^WYvY{%b*gAfgFWA}N;a3)cKvZiyA!Vx!yehZ+ zDti=<8sR_teO{5Kd(c+kC*}`3wz{^1ecN`=YdZ>Bfg5tCAAv|$-rr-DnVK-x8OAsk zrupV^eA6(|mkNG-IiZ?X5+D>GdPWhgSnSAP{Mg^|_+|$ZuQKqegky>e<`_7%YZ$}@ zM40+u{6QCh=`pFK;qdxSFj9Tu=pUXpv&mw5+&mkd!$AJspxOW3X6Fx2XOlA+fse@x z1%}VGNEzR?gxU{%-rAF+N@{cmCu1`c9GOJ91sg0S;M&QHg}Wx4Py^NlXEmX-@pgS^ zZymJr^`V{nTDlIn)!JI+O{pn^V?fA;rz_g1%>&QC1O^E)q4YZ>2iR(Dle3L(n>p)5H=0V4gS3of_m`@BQXy}-N{3LOUgEu+b^38j zRzast4oSd?$VjIdaZIVbo~@>!Lam85VALcK0}EJD0oM^M%rzms)*pEC=fUpF$&2O} zOf)!p4=Wvz@3fhNr`Y`R;OPC`M?U#i@a>A$I+hfS03B^(2&mhIUEN2pPJ)mMtcPJy z1hXc;KC5>(U2QM-T!!!Xp`jR}nct$jb@RgydKX3`ssvD=hAN#en=(=kjo13j^UZUR6RvFw&8%IA9g`Gxc_? zF2xm?GQt0LVudpF`&y+5FYDEAMz8LQdW9rY@xUu4CA>V`$*Nn7Y^-xZolwe2?ep8Q zCbL)=i~~aQBGqDUCENSMnB1cr*3s*Eb`G^^MpD?`RCwM?+Y&k9>~tPutc7 zSKJF50{YnSE&Q=7H-3x%aD1X_>f_;C;2*-0cstU(b>15hPC+TNH&2AWg%ZtBt-vTb z{Nf98)VY0|&NYENO?89EE38iKU@i(j;vO2S(3dIKs35DY012tm}+Su-+4npDk$$S^Wc zPbQG}IV+k+PxI|0BOta()`AV&nijuT!=o0u%JeXXDfTX6BCDnVk;ZP4W3Y6zre8w! zpmTL}rSc3AT|S>2fn;_-1xQ;-8?436bQf9VkJ92@nEF%~<)}^Ii*R!IOac>2mX$}I zK;1-gR5OuCY`P^Obhy)QB7xq&2CTpUrzR4jrgADdT7N3pDNZFv@>H^Grjng&no1<@ zW~P#zXe!wirxIV3)_U%IwyA_w*kKiR!ihmqOUgzw0>@RZin?d2Lap*#vs;{N(%eeu zzv-Dx6afrFR1$(AB?2Mnf;896vU5!YN}IBbS9+A13k0Ub>7&W0S7tm03 zgbt3fx!dya<*sHr4sjihcHD=g!^)vf58$+`UNt~#OlHQT6c0v(DBoHIq@yb}^vy0+;$Kcni(g3Odrw8+U}Cy7^L z)G6sHY2*cc6Mbl3j6RM(PUe4#ku9uR*im3uxS1%Jzmy5|L|6wpHo>QbwV)soS#@VEmb3w#wa)A zXM+%FL^I8jEJ+*o(&Mw-1D73y!m7399Nm?t{z##NdcvAE1<0D=(@5ek3RAeJ?L~Y7 znTYkvj!|nc0$C9dj!GuwBylb;>eiRDOy<183h z{JfBJM1mpZjtODDjX5F|%<RG{^)L z77ebExD0l;2jVb236m`jeY}AQTLCFR{Z>rfRtKu;{KFGyw$(X-nsM%-(nO16JI`99 z@2`jDy%d*A<%n&_nG^GcvCn_f~cEFOYhoiloyI5(>K(^_Hi{TBES<(CQxx!k8?DnsUNF2vm zwciRJS1guHO{GAIH4>kpS4Fp*=C^fHGmI3SR2f(+4HVqD3>Kn0XDhVT$H;+88i7?j zW<@1R^#+|mJI56iEQ>~FNURXUPR=z|7CL|t&H?Lsd)wFG-EFVq+F9jGI&&G?MQ6^b zKbeqfH}2ZpqkyCv@PTSvoYH+zv>!1V56?)JFXlsVDD|N}duTwqGpd{1Rl!TKl3yW5 zD(Fq^es{gC@t_KAkpon3hg_%w|CjKV{yaPzwM#EarIkPip^8tv${&&`@Rh!UoM1bC z%iETZ`2*htVh<1#&NPCtNl1nJo2nm|y&E+$_mpr3w}3Yg;YIsWzHNMbG+E43(xL0= zYh{D_Lzi-U(0u#3s}FusGQ-Ww##3j_6u>euDhxj#n3D{8$9;fp@b@FUnNy9D!TMnP z4y?Khwd*COIJjT7>TVYIw9N_NL&%E57{eMf)LCCJ8V(!8*6g!E5b+{f;!B+I9<*?2 zp@=iR*lefNa2#zVhGn$SCndjxVaL*7&4#MFeggla(p+|k^-C3&Wn%ErOl($b#H1|O zA0{U|UER$Vb^!kzUAZYKXG=b=z?8vFF@=wU&%=~RiWF z?z}nqotR1bqt@0(=eoXaC z{H^V_-=w2+HD1BdAX2e=`}so-Ug4{N?2D&2$2DrI6Me zq!bfgLNakUs6W<>=uh(4{n&DZisyr~BSdl)obXZ^&WTx?F(wR|8cu(AIXs?w$MrmJ zJ^*fd=k_YO>E{j?xJl;_?Gl8uk=wbW@5U4+S&QNn zY>#7y$X)A*&g0s`MjyxrVC^{}?;ztiC_}0MXC8wCu-k>eN=INhIXcIulK$HkT*#vMrNpuc`Y3 zPxs}n+Ub4*#tOPWxF+2n#JWGI*8Rbnx*+AqQMcvts`~L9d8}t8;?== zgW@R)zwgd3=F8mXr;fs745b98NO2hl$0C;zYuS#@B(ylqNC2g_=2fAP- zzw4JK&(KEILXyn5%>he!L>ll zonZOhezX6(PqA{X5u=jTXx+7t+T={ykN9|ucLLiIzzAZV%6DX@+QMqSgbn zvHP2l8qvngLg2Vpj9E4j`L+K<`|{SeQS(}yU1SmpJf}>2*{!dhc1w7+b*FZ2il?m> zL`eZ~W)>93jqBAA+E87k&|5T!nvB>7~-KP&pVBrdiL=~8JRb) zE8!)NfjaJ_=fn&a@l8lVFH!Ua?TKzzxu#-l)BKtt!v;4wA5|=YQ!x>5->WnSQwApU zHC_FJ6J2Sh+q$g@UjNo}e+91xt$5wSRcJRQO6fjko=qmk)U&N{&sDvDH~1W`PQ@rn z&9wc0GFK+no6&CE3%UC8vmA**Te#vm-k}mRyu+)TUG|0-drE|5Zy0fw z^STD^gWm-A!78}lFiv7Jej2Aj$TYp%yVgb@k3T0j^RlT=dhapC%@iI5Zl<JgoH^6RA!W;rUf*uguY zIsz6o+BQgQTfbV{1_f;!{4;7>|9Z5of6dyKx>)Q6wXJ_6+9tWSR(jXv*Qyg-?}ulL zCU9+YOHbaaX7ys6@f9*Wg5yXYEw)DJiI{V9QSOA`g$S3K1Q3%H%Bfw_2>X;d(8uei z`w~32B=jif!5;DY`RRCmcZOFu&bkZ5*2M^l)HC79LnBj_+PLs@?ev+w5uVv|50@;| zG4|;pq~SrM1^$;_iNEW=e6mQre1ZTT@pkdO34s2~iJ~PutTy$i63IBKA>+s=<4B`J za9cg$;VN^m$pyFtwNcskEB^{THhLJVPk?9FV5kXX= zyKwGUb#&7wkF(jR&e8;8S^r=%H*-caBn{U!v<%W_pXhi`t4vSl(o4|yLC&r1f~LoV z%A8(l!m*H9!tX{Y<9CBp9Vm!Edvk#RdqISG655c`XqA>&<}KpXO)%q!=Z1DepoA z-kFuq==@>=jVBk)xH;+kWjegLXr{CH3#FAcCx8TfY%cNR7cS1=q^E9}rpLU3i>AFR zsC{8?CHAGT++AqxLWI=w#dPu>Vo*jk%%+pQ`1;SL1pngW$&{ORzAx&3#ovthEyg3u z2cT@;Ovk_lk0W1EmHF}l){{tj2M5;v7r^)P$;sjjFHAVO&0v$VJ z|Nrmr{;_=@TGM&UzVx|oKM$nO1N(Vb`n>Ca?@QnJ?DriJ{2kYRa965u*P*v3_R!~D z+}Rg_^!II@{k^>%5zc^`_5o{@6O)6-R+$__Xc94vGwl_ z20J^@XlMWK-tL_{dv~`*BKH~7?(XjH-`U;WzO!>@``+GOe_v)`f52pZXS=`K@88|o z-QV8bzc<+F-`VN!-@UT~X!iH+-rem3*0NrJx;VM-ZV&DbcJ=|n_Pw3EyZZnSum_-b zb^+x6-9f*ecXnYo z+}qyX>EGSE+rJBHy1%`*4FufT+qrue)Te)M7l?q~_jh+di=pcNHju%z^yjBPzP$U7 zA0GepzFL{6VYugg@9(<`{e3gU{5m@WS7&G74GF*E{;sRIznf4i*F>TB^haVUVb|kk z#9?nf14sE+#9g;msP}vm!pO5#u!aW&iPJz7Z9Ty-Fecb~wwebHS)jow4)k(kk@3tn zi0iu!etc|LG9Jb(fv<*M_$<*2H4Gh4BS{BTGiX7zG+NML-26&2oKmodolByG=D{nq zPQHY7GM^E`R(Kh8xfxiapdDae(GKRVpdFA?(Qbb?!gEkXA8IgbDY2!;XHWrz$5@d= z972Cj!eTFg5p#>f*y&5G>jyAm&T$y~I}#grLRw-jdc+JQhMbUoSU1JqTe;CTD8Rhd%UtF@=B`#`=D`z`h;;Z^9Mh3vj++ z!LaOh@h(4DIXxnv`q$MJFbx((%dO7vFg~G)D~#j$%gKCr_S5vFp*1JA_LrU0+b<^P z&Hqw?Lbc`u?hJ3MbS_L>7#`|!3L*k=LHi#kW8EIUb-o;p6*k_Q^=z^Q`{`tD(bjHn z*&ft-?bkOWVE)+zx_&d#EE`>*A`ldzi!$A@;4Wb1nynp)q3aNO@qXS!^>Au z3=fGnv`;REzkrUb%l#}0&ztkf`{w^N%UJ>w7|Ej<;z{Am^9}xaQ;Nl3c0S&R5%~Ib z1NyT8Sbf6ayv7>z@{+XjQoa7Git%*{RTuRUDJcQg?HK3{29I~+K|0^Kjigd9>aU)v zqPdF_x&(76U<(~-#A>*i6>FA@L4@bU7K%x&4GwG+Q-PsZGC>T1>;yddtvUvJX?=?x;~P)-J$zue9aKDua<)Tp~slI=hj3@KS zcyw(01a}<+?DI8rK^8sJ4P0<+#Jcc6)CB=q%=(ED#vM&a3!)XrjUi86=oM2P6$y7Q zp(3l=$Iq`GK8))c}&=P5Ou*G*DhYHIbP0{pbvKZw$XAX8k|CHs$R4 zYkPJD^XcWxqmRfFxQRR?!nQgS-=Ue{pPHS>7XUVq*t+!Cy7VwvGEC@iav1=XrRxXV z)UcbX#_aY-*Y}$3+0|5fNrO?vmjhWtEyLn*SZ)C7Ae2=QZR+iKj}g+wf0Mr zp;mtXo(n(bJ$^fyy`6wpOl)~E`XJjBVK7+#Lv!HEFGUty5nv^cO=}`hDL> znOeu%+j&9nU;5VO>JpFcvR5T8@#Vd$(_VPB6y&BiBjj}QS#^$xq1ovYB7)xF_sYAOep3gGWVzu!#8Fjk+= z9?xczl4ff;eD7*Oo|+#^6b37|@GmeB3;pJs-V(Gk<#0jOU~IvU^6o_+6YK*fSKf zr$n*asV;sg$<`fF&=&ptnSPU7DfeoFoeNMDZHm2|g`iqhJM{ z8u+SXD(q1mW@UIx@8WDUe;ldw#bhRpS|~=9255n90fq1lFUf$v;V-?Ro*Ycy!QUV> zoOWKEjgBLYzMO5iAD~?{CxL3we-p@2j=&KAQD`0!R}8MU8h}=)9S%FUZ+DJ-HyE4t z5DK>32+7$O4FC=QdI_2Mg7|c zOlQFgd3Fd;fb6FK>JTd9U+O+A^#$M8!b18JzIcxFw2z)M2jLD4OexWB+IK+Nw;k6m z?7;WErvv48Pj~eBCc!_O4!}X%0-)rlU9ppD&{}&AcJ+jH5hB&5kM2YW2~6koyqr*) zPcWCb937V36U2SspEuoMVAf3T4AK$~7Wtqa4q`MRLya(SixAcqGa&=PmF>Kw3I0{5 zD<0J&AdggAcOeyv>Ah&A=^x8%R}}IDSHlGpq!RUg9M?gJ#uc%v`UzM3s z{IHQqO}V{-BFJ#jnqgsJRrQ0<;y8_eG(U7urX!>3w-ZnE#O?H~12f-tEvZD3daTz_ z7?DlSD+QF2mx+wGumT*zx#GWvvmYnlF2IiC&smJ0ztY+2yk+jWuRGQ$r{cF!F=a%& z^*nUaHCm<44&T}d<_|AN=js6H4~w(;2yknr-JMO&Uyk$Bv2rY`9jkz5OyjPU=jK^PaG=P-(IP~g03R){n)wpyBzB5smdSjYNEyy5-TSWvf$ z5oyoq=w^Ept9-^oTFa`{&@H#P6?D*J%12x46Et%yvcLA_e>tpo|y$8dAz zKCYd5E;`^eIw`uyhjSHln-gscg`}SRpvP>{vbPvM(*6{)FBIuDVLWacar?lpM|@dT zy^>4sK)Gxk3^#j?*x}Dlew&a5{ty+~<(Qpy6LhW@i>975mp`3CGWf%XoBkB`9$YDm z@QZIhy|)gQ6BL___2dd{doRh-S#7k`BeexccK=J&!tDl=Pl0gwj_`K45sccdN$Kji z6cDgkpjz)gXK0@Y3GSBM)6PWapCfAU!z7?HCg?&<0&c=f9579NJ}6~;?>0mgR|xqh zONAFL;vp9Ww@|T*Jjte&MDhiC&L+`+ZPG8gjQGte!oQ?8Z=p8PZHK*=GJ=&7GX&EQ z%nRtcYyqrCz_$T-m{_nKWfh=XG@-rLkkwkTE;bK{1sj|P1PqE4LAUUkMC#k(B8mma z>2Ej&vAT7Zv!l=kP@}rmY;I_>R=@S|bS)ArN(@j-LhC^qwfs#7D%)8` zl0Rj5@)^di)t-0=n@`b5mL%aT;zd#xI(sA)UDWAjqDPa6HBv-VJHb%`h!8GEcNUeEc}JVAx#63NP@55@hnorr z2Q^%UE510l|i&0Ah+Sy|Ex|#A!W? zhk=4gm=6hxTN@%aB}I;#^I^in0f+%gMr=_%a2()ppGRy+&m>bgE_ElOcPXgLfjmT{KQnsSt z7R;;fyD}6jc*TdAd419ivqL`NAV)O8XSOJ9#7nv3gEa z)kRjRlc-mYc+7L+zMdsk0g0wqfnG8b3gzy5gRGfTMf!doe;8dnc)Znl;&h;kKQ~Dc z@aJRPFM|I*32CIZsJXYdl~%Zdezlq~Ac4LxXpv2@+S2vgZw0M3-y`-Tzs&#yo_jL!ZL^^x+TyBWQL?}41QTo?x-qkOvV zn=P02r~%YZr@4{hQGp#Zt@Kn<>!T)z_47k>egvlJ&FJFkIqp`>$TJv?U!&>aYXy_M zD>$rLrf5{=&R@Ui>J?`sdcJk34G{V0N_rnt8vDZ#lMWOPlvU<#H}Dfr5<2$|J9@{w zHwADLpDB3fH83Cig_$2Nrg(s!?c8nROilW}E2dJYJWcswIDd0n^#xzIbhiY}-7d+) zqeF1n)P|AA2sdm^vYo&YbSA~L9M!AN$^lkr;)`{{{UTvxQ@-FKZ>)wlm7A;^CkY3C zWSOq7x`zq^gY#imVx;M#W8pJtbtJy(D2?4VN(MiF7>%!49|_jJPs6JM;8)JIX_0syhXjm9^qa31553KyP0{3W!2Tabk@G1-Rm zi4^6-3c%$#-5?TaqP93x3Ea~89=gs`$nGnKWAUDs(BA5&b>7gOqO4h$S5f*OG)zz^bI6I@Zx`=-Vxq9Xm zO>VKIHxCk$2ysdY%x9LXpX6s^gE&+{A$o8#n&|fzWj>g{1!Lp4TvHic@F3Dj_ldF6 z6owkQOlWA_OvN}3l8SuUQjtRnvih7%6Bl%viNw{XzxkR=(rpQ|aGe&nuVMT3KuHgW zSj`@fPyE)8r_FaTd%<1{q#8@(Bw_Oss+F^I?NuPnh|~a+)uo;Ta*C6n4HX!qYMOGF z*inJDb^-lpfe4{(Hi<;sWeb&3X}o`IUO*(^tkFs9s!+6Jqh#*3S><~wcNJ>|y%u;y zQ2@_YdmBw&R$Cd>Xuochaj`vc&l*UN5h;BuQJM>FXqqTzq09vBV|Kox%B`~eVge%i z--fwtF%GS9d3H#orGh$`W!S6=p;G?ioJzl`Q@bSAW}$;p%+@-Sl#tC3Z;eVSOW4RihB<#2TN zyg6P>XUIp(P&%Mu_CML~*-3LYI@epE&{f8;Q%%|zREu6L!>Ieg{U zp_MxPQIpY+)d-mDABw`QEMf@!0sNqPDr7zjJvZjKg`1apPaYr;0QdIfh~+F8EuvjZ zou`2MK-}#DRxaa)bU}d%^+>U-EUur%c;uxlvaUT3qsBvEP88!%ZXV0ve-OUDWf%s3 zVF^X5{fb|9Ed*+_*^-CaIA}hqvM%Q!ARcgTvzkACYD$hvx@O3%@S*^qklo`7zX&gZ zQ>t9x7k+eCxiap}a$N;n*1bl&?j?Dx(oYm)6-x~>9XF##rS^ZfnO*{aygwSBEEK~} zhoHZoI)53RooU{Gi`@oiRSnZ&Z+KqA2?BLT zJE33MgU}#splS%zh^lz9&;!^oldP6%!H2g+BO2fFL$}^basl|{yKXvMsH#UVx)q08 zXs+5CDm5>Hc}gPa_55r?$tCC{StPcsteC%PUPzMB=61mmOQ>6^RY;-qFrNnx1+4y# z`mGkb==|XT`EfF*ra006w3z1xifF27jxDOEJu%rz*ZxIxXy(+%DTI7pCIv3w_%WHK z20l=O z3cHcI!Y({k7hGgVE#u4Vt`uU`83U?%Iyu9BM}VjP)^eKw;NhuG`^G^8{Oz7nqL}CJ zaQ^Feam_t=TpV~Q<4wy$k!SHtrhY&TG<5n=LPT<_^Bq$gRZfK|jM;;R&!N(H|3u29 zP_$1bsw7WcNaoL_3%YdW6r#Ep2MwBVSb>hI!lI^`$LA7RKW~6O^c#)#9Z=~U{Aw)q zq{lV#z`;cbsI%B6SkwwGqTU3*_;!SA*`o!RVR(lxBK#u z4;{t!+Ak@0+*1NO2wYg$jSDxJuXz*4&6pa#_73sxCCr@tO?PuNN;*-1F(I+7ldNxu zqFi9J)8l^wYDUpS~3KrBmuCzbUZIFaH_mN@+LR&+*hJ zbZiSWcMdf>NvizwQ&zCTRM~~9#$IVJRA;0p?^10C66d8^w9SfE1v?2;!eW{0epB+z z*sZmU);bo8^M>v7u~MId+;s6(?6sP)7%6#7>tU~|AAC-$<}hT2D$=tY?j?0%U_2{R z#G)Ikdnmyb*%{eRe`~&AJ+nGh+=HK-ojhw!=a`VHEGXupsz;vSkI{GpHuG^{Odl5w z3bqSPis=e5JMCf(Vk8)t*naSR9NkQ|4b^C;Z@}Vs8LZfdWnZP5o7d@em|YyY>^v93vqilH9<%Rk}IpzGZHvig7Z+zfcfus8!Xmzv!|KWFpj^B5W&<-lC z!$WNP3v`5EF0l>y9F}%!gLesw$u!qX7~T6%rBw99(BUWxCUw?5c1CdJc^`-yA}2JV zLsT^UZ@9gqSrjIt`bUs*$*A$bXK6cnh)IM2${Oo%z^3+n5d>XE$V}@? z!`;B5YBRg?jG!INE!U|xIb#zsQQ1~6%?TXw)^h?whz71k$V>|Cb3lNtdP9rR+TNX6 zDlj_Hz7_!I&TnaM69Q{zZ?*0x?2@sSPa?a7M(NrNE(-N1FtuoBWm9WxGkr}P-0PxD zSzK#`t1Ye)Pu}F>`8Z>8@ozLa*C^os#fKbf5W}6$Rk=qt;=6I_6mlqe! zvEBcmH-$2%JniY-S#+3}V@*hZ{FGm~`!|`-4)n~;@#^X~A2x%#BTXG2Z+Ca(I_TpW zGM9u(@2J8&WjeucGw=CS_=sCLA3sHpoLcZ$haYw}36BgNYWz{;47N6wfqDZJ=)dea z41+e=6X2t``=uVX{dqispp*+$q;55SF2AB1Ka)#=+04i2B0&Fj+~>j9B$L8pHtd3h z)NpZci6nr2wEPPzE(;aaG-%W$d%v4}Kq`c^G_{suEk=P}(T9iWdk$IZF+-XFVd+Cy zW+8|;7_g=hS2upxNdNJCv&KFV3~Qx~&e}0Asi|PT@~T&79oPQ2? zx~2_PghsYTbAlU+G(W1Jx{mn~$|IZS7eM8@qULWkuTcl?XHJod+LMqp@usS#;>emR z$%S~W+KGVU^)dBhm6R${QCt(-dlh+?gf^|zsC9V9ox0<*`IT<*)VcL9=9p6G@Yn4n zb<&dzfe!R2_!-P`#7vxzHF%tnEkIM3e{9)%IJ(Pp8urM98uqCkvxFKFm90P;4QR?! zwO|hX4=sBYmUTJu+%O&MT9kan98rXhkQc+VT9=eH0Z?H^sflhtRu!vg`^S7(P{z`r z)Xg%3%VKb7K+|~uF9$#IvQFk1OZN#+&1c`>$v-E{UX%R{kI6<@(0gQAOc=1vQf1Sq zJmBS((3z`%*TZ-xdFV|qSdQ}bRfFp*MT8fdbjWotafQ`<0=(28rBm{A68C7ntYold zl6S$4zTYM!5tlkaavsE4mOhzk)h&h!$}}77ThUENpXT~?IiKt%&RJC$HlKoFnmi+eZ*u8dR1=bwbS|)MdUJQFcF%A zQS|x(Yoj6??4*@)tfu8;_J)qXv>ZexiryKhMka z=}}PgioE=Yd~jVS&rf9D60wbsjHNU(mN+tWcgc~lOpgrrDUd^(k)abs_2AGWBST~X=}T8h0iwg`kbwmdOa3@`Sga%yx%)|o>4=CXmS z%-6txtNnqTUoYt_Hq_)gM~M`9D(SHXG?f(D?PuT_cBtdB{KASpbGnyP;K(%n1WZkz zv$lQC{66y|4g9a?!}05;>%VwNH^C}N3OC8oi-$*5cMvK?9-4gKBc;pgljK4l;Zui! z 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 ZP)h{{000000ssO4Z~y=Rg5CfC003@4Luvp3 diff --git a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy index 8790f3e4063..f7b98f15002 100644 --- a/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy +++ b/Source/DafnyStandardLibraries/src/Std/JSON/ZeroCopy/Serializer.dfy @@ -278,6 +278,8 @@ module Std.JSON.ZeroCopy.Serializer { function StructuralView(st: Structural, writer: Writer) : (wr: Writer) ensures wr.Bytes() == writer.Bytes() + Spec.Structural(st, Spec.View) { + hide *; + reveal Writer.Append, Spec.Structural, Spec.View; writer.Append(st.before).Append(st.t).Append(st.after) } diff --git a/Source/IntegrationTests/DafnyDriverLitCommand.cs b/Source/IntegrationTests/DafnyDriverLitCommand.cs index e5d60173707..f4c50c809cc 100644 --- a/Source/IntegrationTests/DafnyDriverLitCommand.cs +++ b/Source/IntegrationTests/DafnyDriverLitCommand.cs @@ -7,6 +7,7 @@ namespace IntegrationTests; delegate Task MainWithWriters(TextWriter outputWriter, TextWriter errorWriter, TextReader inputReader, string[] args); + class MainWithWritersCommand : ILitCommand { private readonly string name; private readonly MainWithWriters main; diff --git a/Source/IntegrationTests/IntegrationTests.csproj b/Source/IntegrationTests/IntegrationTests.csproj index cfb699f0622..f27b11f57cb 100644 --- a/Source/IntegrationTests/IntegrationTests.csproj +++ b/Source/IntegrationTests/IntegrationTests.csproj @@ -24,6 +24,7 @@ +