From 336ac386ae0c70dc4ffdcc11ec64bd1448295162 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Deniz=20=C4=B0rgin?= Date: Sat, 17 Oct 2026 23:31:56 +0300 Subject: [PATCH] test: twelve more declared-error doors become table rows, each door defined once per area TST-E4a P04b. The FileSystem, Integration and Integrations contract classes' declared-error door methods become rows of DeclaredErrorTests, proven on both spines and traced to the pinned spec, in FileSystem/FileSystemDeclaredErrors.cs and Integrations/IntegrationsDeclaredErrors.cs. Each door is defined once per area and its cases reference it, so a door's label and call live in one place. Four retained Integration tests drop member names that no longer exist (GetIntegrationAsync -> GetAsync, PostConnectKeyAsync -> ConnectWithKeyAsync, PostOAuthConnectAsync -> BeginOAuthConnectionAsync). --- .../Common/Errors/DeclaredErrorTests.cs | 4 + .../FileSystemClientContractTests.cs | 52 --------- .../FileSystem/FileSystemDeclaredErrors.cs | 59 ++++++++++ .../IntegrationClientContractTests.cs | 89 +-------------- .../IntegrationsClientContractTests.cs | 25 ---- .../IntegrationsDeclaredErrors.cs | 107 ++++++++++++++++++ tools/jscpd/tests.baseline.json | 101 +++++++---------- 7 files changed, 216 insertions(+), 221 deletions(-) create mode 100644 tests/OpenCode.Sdk.Tests/FileSystem/FileSystemDeclaredErrors.cs create mode 100644 tests/OpenCode.Sdk.Tests/Integrations/IntegrationsDeclaredErrors.cs diff --git a/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs b/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs index 7f912c512..ee1144bba 100644 --- a/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs +++ b/tests/OpenCode.Sdk.Tests/Common/Errors/DeclaredErrorTests.cs @@ -6,8 +6,10 @@ using OpenCode.Sdk.Tests.Credentials; using OpenCode.Sdk.Tests.Debug; using OpenCode.Sdk.Tests.Experimental; +using OpenCode.Sdk.Tests.FileSystem; using OpenCode.Sdk.Tests.Forms; using OpenCode.Sdk.Tests.Harness; +using OpenCode.Sdk.Tests.Integrations; using OpenCode.Sdk.Tests.Support; using OpenCode.Sdk.Tests.Worktrees; @@ -23,6 +25,8 @@ .. CredentialsDeclaredErrors.Rows(), .. DebugDeclaredErrors.Rows(), .. ExperimentalDeclaredErrors.Rows(), .. FormsDeclaredErrors.Rows(), + .. FileSystemDeclaredErrors.Rows(), + .. IntegrationsDeclaredErrors.Rows(), ]; [Test] diff --git a/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemClientContractTests.cs b/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemClientContractTests.cs index 8b64f59a1..ac1e613b5 100644 --- a/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemClientContractTests.cs @@ -52,31 +52,6 @@ await Assert.That(scenario.Requests.Single().RequestUri!.AbsoluteUri) .IsEqualTo("http://localhost:4096/api/fs/list?location[directory]=%2Frepo&path=src"); } - [Test] - public async Task ListEntriesAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.FileSystem.ListEntriesAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task ListEntriesAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.FileSystem.ListEntriesAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - [Test] public async Task FindEntriesAsync_Should_Return_The_Typed_Entries_With_Their_Location() { @@ -109,33 +84,6 @@ await Assert.That(scenario.Requests.Single().RequestUri!.AbsoluteUri) .IsEqualTo("http://localhost:4096/api/fs/find?query=todo&type=directory&limit=10"); } - [Test] - public async Task FindEntriesAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.FileSystem.FindEntriesAsync(new FsFindRequest { Query = "todo" })) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task FindEntriesAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.FileSystem.FindEntriesAsync( - new FsFindRequest { Query = "todo" }, - OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - /// /// A file is raw bytes, not text: bytes that are not valid UTF-8 come back unchanged, beside /// the Content-Type the server declared from the file's extension. diff --git a/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemDeclaredErrors.cs new file mode 100644 index 000000000..f2909b20a --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/FileSystem/FileSystemDeclaredErrors.cs @@ -0,0 +1,59 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.FileSystem; + +public static class FileSystemDeclaredErrors +{ + private static readonly DeclaredErrorDoor ListEntriesDoor = new( + nameof(FileSystemClient.ListEntriesAsync), + "fs.list", + "get", + "/api/fs/list", + static async (client, options) => await client.FileSystem.ListEntriesAsync(requestOptions: options)); + + private static readonly DeclaredErrorDoor FindEntriesDoor = new( + nameof(FileSystemClient.FindEntriesAsync), + "fs.find", + "get", + "/api/fs/find", + static async (client, options) => await client.FileSystem.FindEntriesAsync(new FsFindRequest { Query = "todo" }, options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "fs.list:400:InvalidRequestError", + ListEntriesDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1fs~1list/get/responses/400/content/application~1json/schema"), + static () => new( + "fs.list:401:UnauthorizedError", + ListEntriesDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1fs~1list/get/responses/401/content/application~1json/schema"), + static () => new( + "fs.find:400:InvalidRequestError", + FindEntriesDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1fs~1find/get/responses/400/content/application~1json/schema"), + static () => new( + "fs.find:401:UnauthorizedError", + FindEntriesDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1fs~1find/get/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tests/OpenCode.Sdk.Tests/Integrations/IntegrationClientContractTests.cs b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationClientContractTests.cs index f43b1fc21..4ac1e4def 100644 --- a/tests/OpenCode.Sdk.Tests/Integrations/IntegrationClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationClientContractTests.cs @@ -24,7 +24,7 @@ await Assert.That(scenario.Requests.Single().RequestUri) } [Test] - public async Task GetIntegrationAsync_Should_Return_The_Typed_Integration() + public async Task GetAsync_Should_Return_The_Typed_Integration() { const string integration = "{\"id\":\"int_1\",\"name\":\"GitHub\",\"methods\":[],\"connections\":[]}"; using var scenario = ContractScenario.Responding(HttpStatusCode.OK, WireBodyData.LocationEnvelope(integration)); @@ -41,7 +41,7 @@ await Assert.That(scenario.Requests.Single().RequestUri) } [Test] - public async Task GetIntegrationAsync_Should_Throw_The_Declared_404_When_The_Integration_Is_Unknown() + public async Task GetAsync_Should_Throw_The_Declared_404_When_The_Integration_Is_Unknown() { using var scenario = ContractScenario.Responding(HttpStatusCode.NotFound, WireBodyData.IntegrationNotFoundError); @@ -55,33 +55,7 @@ public async Task GetIntegrationAsync_Should_Throw_The_Declared_404_When_The_Int } [Test] - public async Task GetIntegrationAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Integrations.GetIntegrationClient("int_1").GetAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task GetIntegrationAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Integrations.GetIntegrationClient("int_1") - .GetAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - - [Test] - public async Task PostConnectKeyAsync_Should_Send_The_Typed_Body_On_The_Handle_Route() + public async Task ConnectWithKeyAsync_Should_Send_The_Typed_Body_On_The_Handle_Route() { using var scenario = ContractScenario.Responding(HttpStatusCode.NoContent, string.Empty); @@ -96,35 +70,7 @@ public async Task PostConnectKeyAsync_Should_Send_The_Typed_Body_On_The_Handle_R } [Test] - public async Task PostConnectKeyAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Integrations.GetIntegrationClient("int_1") - .ConnectWithKeyAsync(new IntegrationConnectKeyRequest { Key = "sk-test" })) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task PostConnectKeyAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Integrations.GetIntegrationClient("int_1").ConnectWithKeyAsync( - new IntegrationConnectKeyRequest { Key = "sk-test" }, - requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } - - [Test] - public async Task PostOAuthConnectAsync_Should_Return_The_Typed_Attempt() + public async Task BeginOAuthConnectionAsync_Should_Return_The_Typed_Attempt() { const string attempt = "{\"attemptID\":\"att_1\",\"url\":\"https://example.test/authorize\"," + "\"instructions\":\"Open the link\",\"mode\":\"auto\",\"time\":{\"created\":1,\"expires\":2}}"; @@ -141,31 +87,4 @@ await Assert.That(scenario.Requests.Single().RequestUri) await Assert.That(scenario.Requests.Single().Body).IsEqualTo("{\"methodID\":\"github\"}"); } - [Test] - public async Task PostOAuthConnectAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Integrations.GetIntegrationClient("int_1") - .BeginOAuthConnectionAsync(new IntegrationOAuthConnectRequest { MethodId = "github" })) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task PostOAuthConnectAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Integrations.GetIntegrationClient("int_1").BeginOAuthConnectionAsync( - new IntegrationOAuthConnectRequest { MethodId = "github" }, - requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } } diff --git a/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsClientContractTests.cs b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsClientContractTests.cs index 792a4f537..8e532b5a5 100644 --- a/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsClientContractTests.cs +++ b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsClientContractTests.cs @@ -1,5 +1,4 @@ using System.Net; -using OpenCode.Sdk.Models; using OpenCode.Sdk.Tests.Support; namespace OpenCode.Sdk.Tests.Integrations; @@ -45,28 +44,4 @@ public async Task ListIntegrationsAsync_Should_Return_An_Empty_List() await Assert.That(response.Integrations).IsEmpty(); } - [Test] - public async Task ListIntegrationsAsync_Should_Throw_The_Declared_400_Error() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.BadRequest, WireBodyData.InvalidRequestError); - - var exception = await Assert - .That(async () => _ = await scenario.Client.Integrations.ListIntegrationsAsync()) - .Throws(); - - await Assert.That(exception!.Status).IsEqualTo(400); - await Assert.That(exception.Error).IsTypeOf(); - } - - [Test] - public async Task ListIntegrationsAsync_Should_Return_The_401_Error_On_The_NoThrow_Spine() - { - using var scenario = ContractScenario.Responding(HttpStatusCode.Unauthorized, WireBodyData.UnauthorizedError); - - var response = await scenario.Client.Integrations.ListIntegrationsAsync(requestOptions: OpenCodeRequestOptions.NoThrow); - - await Assert.That(response.IsError).IsTrue(); - await Assert.That(response.Status).IsEqualTo(401); - await Assert.That(response.Error).IsTypeOf(); - } } diff --git a/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsDeclaredErrors.cs b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsDeclaredErrors.cs new file mode 100644 index 000000000..61e7e12dc --- /dev/null +++ b/tests/OpenCode.Sdk.Tests/Integrations/IntegrationsDeclaredErrors.cs @@ -0,0 +1,107 @@ +using System.Net; +using OpenCode.Sdk.Models; +using OpenCode.Sdk.Tests.Common.Support; +using OpenCode.Sdk.Tests.Support; + +namespace OpenCode.Sdk.Tests.Integrations; + +public static class IntegrationsDeclaredErrors +{ + private static readonly DeclaredErrorDoor GetDoor = new( + nameof(IntegrationClient.GetAsync), + "integration.get", + "get", + "/api/integration/{integrationID}", + static async (client, options) => await client.Integrations.GetIntegrationClient("int_1").GetAsync(requestOptions: options)); + + private static readonly DeclaredErrorDoor ConnectWithKeyDoor = new( + nameof(IntegrationClient.ConnectWithKeyAsync), + "integration.connect.key", + "post", + "/api/integration/{integrationID}/connect/key", + static async (client, options) => await client.Integrations.GetIntegrationClient("int_1").ConnectWithKeyAsync( + new IntegrationConnectKeyRequest { Key = "sk-test" }, options)); + + private static readonly DeclaredErrorDoor BeginOAuthConnectionDoor = new( + nameof(IntegrationClient.BeginOAuthConnectionAsync), + "integration.oauth.connect", + "post", + "/api/integration/{integrationID}/connect/oauth", + static async (client, options) => await client.Integrations.GetIntegrationClient("int_1").BeginOAuthConnectionAsync( + new IntegrationOAuthConnectRequest { MethodId = "github" }, options)); + + private static readonly DeclaredErrorDoor ListIntegrationsDoor = new( + nameof(IntegrationsClient.ListIntegrationsAsync), + "integration.list", + "get", + "/api/integration", + static async (client, options) => await client.Integrations.ListIntegrationsAsync(requestOptions: options)); + + public static IEnumerable> Rows() => + [ + static () => new( + "integration.get:400:InvalidRequestError", + GetDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1integration~1{integrationID}/get/responses/400/content/application~1json/schema"), + static () => new( + "integration.get:401:UnauthorizedError", + GetDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1integration~1{integrationID}/get/responses/401/content/application~1json/schema"), + static () => new( + "integration.connect.key:400:InvalidRequestError", + ConnectWithKeyDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1integration~1{integrationID}~1connect~1key/post/responses/400/content/application~1json/schema"), + static () => new( + "integration.connect.key:401:UnauthorizedError", + ConnectWithKeyDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1integration~1{integrationID}~1connect~1key/post/responses/401/content/application~1json/schema"), + static () => new( + "integration.oauth.connect:400:InvalidRequestError", + BeginOAuthConnectionDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1integration~1{integrationID}~1connect~1oauth/post/responses/400/content/application~1json/schema"), + static () => new( + "integration.oauth.connect:401:UnauthorizedError", + BeginOAuthConnectionDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1integration~1{integrationID}~1connect~1oauth/post/responses/401/content/application~1json/schema"), + static () => new( + "integration.list:400:InvalidRequestError", + ListIntegrationsDoor, + HttpStatusCode.BadRequest, + WireBodyData.InvalidRequestError, + "InvalidRequestError", + typeof(InvalidRequestError), + "#/paths/~1api~1integration/get/responses/400/content/application~1json/schema"), + static () => new( + "integration.list:401:UnauthorizedError", + ListIntegrationsDoor, + HttpStatusCode.Unauthorized, + WireBodyData.UnauthorizedError, + "UnauthorizedError", + typeof(UnauthorizedError), + "#/paths/~1api~1integration/get/responses/401/content/application~1json/schema"), + ]; +} diff --git a/tools/jscpd/tests.baseline.json b/tools/jscpd/tests.baseline.json index fa6c116ca..592d1c164 100644 --- a/tools/jscpd/tests.baseline.json +++ b/tools/jscpd/tests.baseline.json @@ -5,18 +5,15 @@ "00342d539c7b0bf9": 1, "01417d72ad1b123c": 1, "01b50a050ff5cb57": 1, - "01dcc53ff3eec92e": 1, - "0281a275a0fcf9f5": 1, "02d421174ecab381": 1, "030445ef25b69be7": 1, "030b9be65c2b2225": 1, "032245d683ed5066": 1, "0341de072c280e0e": 2, + "0395a00037a917b8": 1, "03f0da59b2a78217": 1, - "047178ad85b36704": 1, "059dcd6e0a494338": 1, "060d60ecdc435655": 1, - "06656fd8e84d7308": 1, "06f41df1aeaf1cd9": 1, "073ba1f3be6c91d0": 1, "073d220255049f78": 1, @@ -30,7 +27,6 @@ "098fb3bcb2fb04a3": 1, "09cdd0045baeeb79": 1, "0a0c79f212dac8aa": 1, - "0a3c56da01d57546": 1, "0a6e5c2d3b8c81ff": 1, "0a83952fafd4de0d": 1, "0b1dd9528bf9f4d7": 1, @@ -48,12 +44,13 @@ "10003a5ebdb1faa9": 1, "1035e50fc18d0089": 1, "10ae734f6c09cd4d": 1, - "10b1f125bff80a24": 1, + "10e65016e739cc98": 1, "113cc076f3fdaac2": 1, "116939c0012f36db": 1, "118f6000645c9441": 1, "11bf507ea1387ebc": 1, "11e6156620b2560f": 1, + "122567aef968827c": 1, "125ee26a2b20b167": 1, "13211ae1b77d178e": 1, "139a4466552f7894": 1, @@ -62,12 +59,10 @@ "14284878346f6672": 1, "14f3cf459e8fd59e": 1, "14f4b594979ef4be": 1, - "1541fbb4d4169e3b": 1, "15f72a1f46f3211c": 1, + "16abac940e1137ea": 1, "171c27993e2f8380": 1, "17537e2a94773132": 1, - "17ab2b36ae54f58c": 1, - "1893ade463908aa8": 1, "18b20d9b8321f296": 1, "1909d5d413d0fafa": 1, "1af631b28fef999f": 1, @@ -98,6 +93,7 @@ "24c472b27799aec8": 1, "24cc85d24f0b3dfa": 1, "2550fac4318fc198": 1, + "255c30af16e9acf0": 1, "255c9c6d8752d5b1": 1, "25868f84187d3eb9": 1, "26bcf1eae13cefb9": 1, @@ -115,39 +111,33 @@ "2cd64c5a0bd7b129": 1, "2d01f1bea1f9ea7e": 1, "2d0c7764aa30effc": 1, + "2d84f5d49f525727": 1, "2e6446a9c3e54be2": 1, "2ebc929ec99531d7": 1, "2ef093de84b22985": 1, "2fa52323893c6990": 1, "2fce9f9be54d9810": 1, "2fcfde38c702a305": 1, - "2fd59fd21a10a274": 1, "30024875e03c93af": 1, "303aee7f7b8af88f": 1, "3081885a80a22be3": 1, "3095017bef402cf6": 1, - "30bb2b9ad95556f7": 1, "30c6457c90ba767e": 1, - "30ced3581af45822": 1, - "30cf7167ef1b22a3": 1, "31079b601cabad85": 1, "325aedadc9c51610": 1, + "32813351a4512ab1": 1, + "328f8d27e9d17017": 1, "32a53e20ee7c711b": 1, - "34000b667aa1909e": 1, "34812987b8a4a722": 1, - "34fcf0ae76620da9": 1, "350995582d58fa70": 1, "365bc439e50e1c16": 1, - "366c2d108bd284de": 1, "36c9a7fe23bd443f": 1, - "371c4674c25c1ba2": 1, "3787bbf8fd3bb831": 1, "37e7cf7d45ffba52": 1, "381a9b351137f9ca": 1, "3882460d4ac3aa39": 1, + "38da175c3f3263ab": 1, "395bcea3b3a0f37b": 1, - "39d2972d41c80376": 1, - "3a246ada37b9d048": 1, "3a31a52bec51fb1d": 1, "3a87c8a45e85cc43": 1, "3aa741762878529d": 1, @@ -167,7 +157,6 @@ "3f1d04fcf9712e5d": 1, "3f3dbe95e1417a1b": 3, "3f95418f86463b66": 1, - "40dcbe1aa5ea0aa6": 1, "41005cc85152f877": 1, "410855c256ca33cf": 1, "411f04f073e9ad3f": 1, @@ -178,11 +167,13 @@ "442313bd038e5928": 1, "44259b731f378b4b": 1, "4489253ca84315db": 1, + "46838631f0c798bd": 1, "479fdc49d7da2d6e": 1, "47c6dec036a94d60": 1, "47d341670708569a": 1, "482c654299e74350": 1, - "483ed1bb08a9eef3": 1, + "4889b45748ec205e": 1, + "48c32c7eaffb48de": 1, "48c83373cc2d7d8d": 1, "492f8010b57edfcf": 1, "49432516d8bdce34": 1, @@ -190,8 +181,10 @@ "4a0c669010ce3ce8": 1, "4a6d9e9744168596": 1, "4a9224a89db2ae4d": 1, + "4aa9c49e32bbfeda": 1, "4aaa9d6fd117dacd": 1, "4b7b758e168bab6a": 1, + "4b8e5202cfba2e1a": 1, "4ba929d61eb40117": 1, "4c3f0df710b0e5d4": 1, "4ccca39676639bbf": 1, @@ -205,7 +198,6 @@ "52c3af1ca095f904": 1, "54a00ea64bca1d6f": 1, "54a6b2a26aec6926": 1, - "54b81fbb791e6864": 1, "54b9c19635b2d532": 1, "554f27198300c077": 1, "557d9ce8017ed9e9": 1, @@ -214,15 +206,14 @@ "561f3f3bf4df34b5": 1, "56446320884d2a6b": 1, "567e66ef84568376": 2, + "5684435994da0e61": 1, "573c75d83c9a3c95": 1, "57470feca6bbb65f": 1, "57f025d61c1ae125": 1, "580bb3a45cc1aa00": 1, - "582bada14b0680c6": 1, "5890b6797611cdbf": 1, "58cf3aedc0f4f1c5": 1, "58df2dce6a57ddc3": 1, - "592128a9b607f5ab": 1, "5977e81f73804251": 1, "5ae402699aab9b4f": 1, "5b5f89cf29e631cb": 1, @@ -233,10 +224,10 @@ "5c956c46330fb9c3": 1, "5cb2e7e9a7e11a37": 1, "5d5ef92942ea8a4b": 1, - "5de3f61eebf4f087": 1, "5e13371fd2b2249a": 1, "5f5853703072392b": 1, "5f76879862027b63": 1, + "5fbb8861f104dd86": 1, "5fc40824eff9ddbe": 1, "5fce21230688a4cc": 1, "5fea5678f28a491f": 1, @@ -250,11 +241,9 @@ "63ccee6cade2a08c": 1, "645f364bb0fb02ea": 1, "647d48d7086c2f8d": 1, - "64c07f90ee3979fc": 1, "65c592402d3c35db": 1, "666a7f0d59bdfda9": 1, "673cdefbc0e27446": 1, - "674b01d92c72d2fa": 1, "67f863244c398a2e": 1, "686f4cbec8a0fd92": 1, "687d5ab065e65e16": 1, @@ -267,14 +256,13 @@ "6ba2cd7a4868cb82": 1, "6bbbe6bbf34d4b4a": 1, "6bc1a56f488e732f": 1, - "6c143e6d5b470a14": 1, "6c383a49efeb60f2": 1, "6c8b4fa34ddcf1cf": 1, "6cc50d702b0cf2cf": 1, "6ce49ad646f4a55d": 1, - "6ce7d068cf7d63e8": 1, "6d2315e42adf5051": 1, "6d348ca9871cd43b": 1, + "6d93ccc53ef1ac50": 1, "6e28853461e0f610": 1, "6e3557268fbb6d7b": 1, "6e7989c97054cdff": 1, @@ -283,7 +271,6 @@ "6ed8b7b89c38fd7f": 1, "6ee3e67f6a10362e": 1, "6efa92670898d4c4": 1, - "6fd6a008b9edbcad": 1, "7015815c99e52132": 1, "706c80b864b19699": 1, "70b546f19e61694e": 1, @@ -298,7 +285,6 @@ "7438b1eeebb9c879": 1, "74ab566488e0a7b5": 1, "74bad6b365aeb9ef": 1, - "753b739aff6551a0": 1, "755f26525b4fa26d": 1, "75aa297e7148b393": 1, "75e50c1abd5451b7": 1, @@ -309,21 +295,22 @@ "7931cdb3741c2bb8": 1, "7943699770a884f4": 1, "796944d81a86d537": 1, - "7979ae4cefb88a17": 1, "7ab4fed3be6bca2c": 1, "7b16854634035afe": 1, "7b29c98f174c4aad": 1, "7b66455caf235ad7": 1, + "7ba3d80569d00387": 1, "7baca2d0e7c78a56": 1, + "7bdaf1f09dad093c": 1, "7c4d439b46ebc8bf": 1, "7cb3773f240a7d3b": 1, "7da92939d4cdca00": 1, "7e09a30a918c9d2f": 1, "7ea14f75d7412427": 1, - "7eda659709115c79": 1, "7eda9e729d5869ca": 1, "7ee9b7831ad8eeb9": 1, "7f8b8b1b7f8ac7c9": 1, + "7fbd532cf3994d55": 1, "7ffcd9e9160f6b45": 1, "80cc7036ff095cb9": 1, "813356530d4e26c5": 1, @@ -335,9 +322,11 @@ "82d68551f5be56b4": 1, "83cf50adb5c58985": 1, "84029d744b2215c7": 1, + "8458e7946245ca5d": 1, "852958b905b8447d": 1, "852e00262bbefd12": 1, "859240ba1081004a": 1, + "863bcdab05f4bbc0": 1, "86629d252be8ae75": 1, "868313d60a5b083d": 1, "86c12e9faa8ad5f5": 1, @@ -352,7 +341,6 @@ "8a7412eb78a37817": 1, "8a7e47959ada7043": 1, "8adcbd3f74c61e25": 1, - "8c76e81987466f89": 1, "8d130dcf8156d446": 1, "8dbef398f2f6ca1a": 1, "8dc9324256cda03a": 1, @@ -362,7 +350,6 @@ "8eac88e1c62578f7": 1, "8fb533df3ad5143e": 1, "8fcd5cc8f352b66c": 1, - "8fe075c7a07d77c5": 1, "90832cdd704dea7f": 1, "90911bb723015f18": 1, "90e2d0b4e68471be": 1, @@ -374,19 +361,19 @@ "926d6280af25895e": 1, "92a23a8351ac6f5b": 1, "93c7ffbef646d5bd": 1, + "942a5e56acc61557": 1, "94c3b038871234a4": 1, "950d14b87d7527d0": 1, "9676160daa1042e5": 1, "96af7cbd3e81daa0": 1, "9720751d6958956a": 1, "97413e8ff5b212d1": 1, - "9857d1c8d34efbc3": 1, + "985a8783503aefa6": 1, "98c9c3613c3d13da": 1, "98cf46d5ad809549": 1, "99234a03fbba27b8": 1, "99a67420ab2fdabd": 2, "99ab2f421483cca1": 1, - "99d5a509c3e89f68": 1, "9a6d3e40660da4b5": 1, "9afaad4e059435eb": 1, "9b108a480389775d": 1, @@ -398,6 +385,7 @@ "9e3047781f98341c": 1, "9e6b559433dd1ad6": 1, "9ef5a8b0fb2c88e7": 1, + "9f37b8cd6d068f2b": 1, "9fafa1f7c850803c": 1, "a184ce7305097ded": 1, "a26cf9c1d71dd814": 1, @@ -413,14 +401,16 @@ "a7842c59f67aee3e": 1, "a7ce419852c3f4bb": 1, "a888b3cdad3d452d": 1, + "a90556221babeb5a": 1, "a97d033336de820c": 1, "aa6af3c307cb3b1b": 1, "aa8c5d1539d3f39d": 1, "aac0860cac7db3e7": 1, "ab7663e0d5d61f22": 1, "abde2f4fe3b18cbc": 1, - "ac7e74bc96f5e3e2": 1, + "ad4e14f46a1fa4de": 1, "ad57d9f03fc15ff1": 1, + "adb8f429521df254": 1, "aeab9ff4f97a36dc": 1, "aed35329e94d587d": 1, "af1f63f59181ebb2": 1, @@ -428,10 +418,12 @@ "aff1b8c4442aff99": 1, "b03618789a68ee62": 1, "b04ce5425f684986": 1, + "b05721f4644d20a0": 1, "b0dcb57bb0a78e76": 1, "b11e207acaec82c8": 1, "b17bbc10f934e336": 1, "b26ec09aa9c7d788": 1, + "b402646e76b940bc": 1, "b4f1d187378630d2": 1, "b516fc87f57ff552": 1, "b56ef55aaf8bf7ba": 1, @@ -443,11 +435,9 @@ "b75d56bd3c856ce4": 1, "b7bc3b0fc7ddd824": 1, "b8a1c1219d14b2ef": 1, - "b8be2338cae1b8ef": 1, "b914a2a0e162a6cf": 1, "b94d40e5ff48eda4": 1, "b9a2eed0186fe069": 1, - "b9bfa4f18870b9ac": 1, "ba1b81c7dacd299e": 1, "ba50dc522914af62": 1, "ba8d50bcd5dc7b3d": 1, @@ -459,16 +449,13 @@ "bd4f6c118914566e": 1, "bd643f472e0aade2": 1, "bda28c725d186ab6": 1, + "bdb7ce92fff6e412": 1, "be0798753bf869c4": 1, - "be135361a689e451": 1, "be5d978af35181b1": 1, - "bf543efb3bf179b7": 1, - "bf770211d6bd31c8": 1, "c045ab0efa440e92": 1, "c0489425c5faec0f": 1, "c088cecf620e0f51": 1, "c0d167f4b47c21a7": 1, - "c157d27a8b5765a1": 1, "c15cc20a8eb5b54e": 1, "c16ea8d19b585fb5": 1, "c194aa2d8a81a46b": 1, @@ -478,11 +465,10 @@ "c59efd159d199356": 1, "c661cc78e1086df2": 1, "c6cce4bd6bf12d59": 1, - "c7337d0c6bea8644": 1, - "c91931715dd5082a": 1, - "c91fb1cb08b23e1c": 1, + "c94857b72d464212": 1, "c99b81e4ed3d76fb": 1, "c99b9aa8b9c89f27": 1, + "c9bbce25ca3ab0c1": 1, "ca23d20b55a208df": 1, "ca52433f79ca9adf": 1, "cb72f4a5d460e4a8": 1, @@ -494,20 +480,18 @@ "ce8da66742f7122d": 1, "ced268f3432a0391": 1, "ceed549c863ce378": 1, + "cf8f8d9f44328f15": 1, "d13f1005c59d1243": 1, "d20c4d175159aa90": 1, - "d2c06a0c703438be": 1, "d342abdc73d730f0": 1, "d3b20c2767eef0a5": 1, "d4c8152dde214d7d": 1, "d5292d9905239a48": 1, - "d63808fd25912f20": 1, "d6a35efc223b35f0": 1, "d6ea4ed36005aa7c": 1, "d74223b54c1e2a1b": 1, "d7469c3929718224": 1, "d7907d003a1d9fca": 1, - "d7951c97c2de818f": 1, "d829295842cacb52": 1, "d8472070574df3a0": 1, "d8ad9bee4beede6f": 1, @@ -516,7 +500,6 @@ "d98319a346958e32": 1, "dbbafe3c109191e2": 1, "dbfef984a824b22e": 1, - "dd1bb0d0c2b16718": 1, "ddab192463f1ade4": 1, "de1435ae5e214376": 1, "de25b177ad221b80": 1, @@ -534,19 +517,18 @@ "e539609f53bb27d3": 1, "e59cfed574cd3816": 1, "e6460fb624a61900": 1, - "e7a6b9d06ebbf88b": 1, "e7e34567eac6357c": 1, "e824191acfff90d2": 1, "e82d1f2daab210ec": 1, "e841f14c1576be4d": 1, "e880470757e4f716": 1, "e9a4f95d6cc5b939": 1, - "eab34e08a59a2311": 1, + "ea178bb1fa8ad8a6": 1, "eaee9a41a0b130d0": 1, "eb0bbed02f67f613": 1, "ebec59933509b551": 1, "ebfeb862351f9538": 1, - "ec785bc2c1102cd0": 1, + "ec0ee1421b89f375": 1, "ecefd42b73bc5e3c": 1, "ed10c82591b10abb": 1, "ed54a54bce71c168": 1, @@ -563,22 +545,19 @@ "f102cbf1fab8a3d9": 1, "f176cdac923927ee": 1, "f1812b941eb02542": 1, - "f1a3c57f33f8ce46": 1, "f1f7493a31b45480": 1, + "f23585e99b5a0ecb": 1, "f23a5dc8edef52e2": 1, "f279b2bb369cd7f1": 1, "f29076103ef900ac": 1, - "f30c07e6eec3d0d8": 1, "f366e666acd97894": 1, "f37319ef3f0e2c88": 1, "f3bfe6c708e83755": 1, "f3caece08093c884": 1, "f3d16a0490547ad5": 1, "f3dce7104ce46e6e": 1, - "f471bd1f58c00225": 1, "f47aa4755d742c49": 1, "f495e9854c7890f3": 1, - "f4b1049c2de5b4b5": 1, "f520e28c48e38582": 1, "f55fe2c61cba9980": 1, "f56fbb7ea258b2f9": 1, @@ -586,14 +565,18 @@ "f668e8d378c310b8": 1, "f742e38e8b79f879": 1, "f79fd5643e4c8d70": 1, + "f7da06bb4a76e08f": 1, "f86d15fdd5782fbd": 1, + "f87f93239913891b": 1, "f92cfe72d5df13f4": 1, + "f963eb3d6a7fe548": 1, "f97e3c6571c051bf": 1, "f981c9a75c497712": 1, - "fa95e7b4ee1bc5ae": 1, + "faf56416bef9aae6": 1, "fc541ae4aa953e03": 1, "fd0c45c2afe9457e": 1, "fd0d3c8ea8788bd8": 1, + "fd4fcd6fb9ff2850": 1, "fd70d83572dba2c6": 1, "ff3cf605f2c42eb9": 1, "ff6242fa9aa38b74": 1,