Skip to content

Conversation

@renovate
Copy link
Contributor

@renovate renovate bot commented Apr 16, 2024

This PR contains the following updates:

Package Change Age Confidence
effect (source) 2.2.5 -> 3.18.4 age confidence

Release Notes

Effect-TS/effect (effect)

v3.18.4

Compare Source

Patch Changes
  • #​5617 6ae2f5d Thanks @​gcanti! - JSONSchema: Fix issue where invalid defaults were included in the output.

    Now they are ignored, similar to invalid examples.

    Before

    import { JSONSchema, Schema } from "effect"
    
    const schema = Schema.NonEmptyString.annotations({
      default: ""
    })
    
    const jsonSchema = JSONSchema.make(schema)
    
    console.log(JSON.stringify(jsonSchema, null, 2))
    /*
    Output:
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "description": "a non empty string",
      "title": "nonEmptyString",
      "default": "",
      "minLength": 1
    }
    */

    After

    import { JSONSchema, Schema } from "effect"
    
    const schema = Schema.NonEmptyString.annotations({
      default: ""
    })
    
    const jsonSchema = JSONSchema.make(schema)
    
    console.log(JSON.stringify(jsonSchema, null, 2))
    /*
    Output:
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "description": "a non empty string",
      "title": "nonEmptyString",
      "minLength": 1
    }
    */

v3.18.3

Compare Source

Patch Changes
  • #​5612 25fab81 Thanks @​gcanti! - Fix JSON Schema generation with topLevelReferenceStrategy: "skip", closes #​5611

    This patch fixes a bug that occurred when generating JSON Schemas with nested schemas that had identifiers, while using topLevelReferenceStrategy: "skip".

    Previously, the generator would still output $ref entries even though references were supposed to be skipped, leaving unresolved definitions.

    Before

    import { JSONSchema, Schema } from "effect"
    
    const A = Schema.Struct({ value: Schema.String }).annotations({
      identifier: "A"
    })
    const B = Schema.Struct({ a: A }).annotations({ identifier: "B" })
    
    const definitions = {}
    console.log(
      JSON.stringify(
        JSONSchema.fromAST(B.ast, {
          definitions,
          topLevelReferenceStrategy: "skip"
        }),
        null,
        2
      )
    )
    /*
    {
      "type": "object",
      "required": ["a"],
      "properties": {
        "a": {
          "$ref": "#/$defs/A"
        }
      },
      "additionalProperties": false
    }
    */
    console.log(definitions)
    /*
    {
      A: {
        type: "object",
        required: ["value"],
        properties: { value: [Object] },
        additionalProperties: false
      }
    }
    */

    After

    import { JSONSchema, Schema } from "effect"
    
    const A = Schema.Struct({ value: Schema.String }).annotations({
      identifier: "A"
    })
    const B = Schema.Struct({ a: A }).annotations({ identifier: "B" })
    
    const definitions = {}
    console.log(
      JSON.stringify(
        JSONSchema.fromAST(B.ast, {
          definitions,
          topLevelReferenceStrategy: "skip"
        }),
        null,
        2
      )
    )
    /*
    {
      "type": "object",
      "required": ["a"],
      "properties": {
        "a": {
          "type": "object",
          "required": ["value"],
          "properties": {
            "value": { "type": "string" }
          },
          "additionalProperties": false
        }
      },
      "additionalProperties": false
    }
    */
    console.log(definitions)
    /*
    {}
    */

    Now schemas are correctly inlined, and no leftover $ref entries or unused definitions remain.

v3.18.2

Compare Source

Patch Changes

v3.18.1

Compare Source

Patch Changes

v3.18.0

Compare Source

Minor Changes
  • #​5302 1c6ab74 Thanks @​schickling! - Add experimental Graph module with comprehensive graph data structure support

    This experimental module provides:

    • Directed and undirected graph support
    • Immutable and mutable graph variants
    • Type-safe node and edge operations
    • Graph algorithms: DFS, BFS, shortest paths, cycle detection, etc.

    Example usage:

    import { Graph } from "effect"
    
    // Create a graph with mutations
    const graph = Graph.directed<string, number>((mutable) => {
      const nodeA = Graph.addNode(mutable, "Node A")
      const nodeB = Graph.addNode(mutable, "Node B")
      Graph.addEdge(mutable, nodeA, nodeB, 5)
    })
    
    console.log(
      `Nodes: ${Graph.nodeCount(graph)}, Edges: ${Graph.edgeCount(graph)}`
    )
  • #​5302 70fe803 Thanks @​mikearnaldi! - Automatically set otel parent when present as external span

  • #​5302 c296e32 Thanks @​tim-smart! - add Effect.Semaphore.resize

  • #​5302 a098ddf Thanks @​mikearnaldi! - Introduce ReadonlyTag as the covariant side of a tag, enables:

    import type { Context } from "effect"
    import { Effect } from "effect"
    
    export class MyRequirement extends Effect.Service<MyRequirement>()(
      "MyRequirement",
      { succeed: () => 42 }
    ) {}
    
    export class MyUseCase extends Effect.Service<MyUseCase>()("MyUseCase", {
      dependencies: [MyRequirement.Default],
      effect: Effect.gen(function* () {
        const requirement = yield* MyRequirement
        return Effect.fn("MyUseCase.execute")(function* () {
          return requirement()
        })
      })
    }) {}
    
    export function effectHandler<I, Args extends Array<any>, A, E, R>(
      service: Context.ReadonlyTag<I, (...args: Args) => Effect.Effect<A, E, R>>
    ) {
      return Effect.fn("effectHandler")(function* (...args: Args) {
        const execute = yield* service
        yield* execute(...args)
      })
    }
    
    export const program = effectHandler(MyUseCase)

v3.17.14

Compare Source

Patch Changes

v3.17.13

Compare Source

Patch Changes

v3.17.12

Compare Source

Patch Changes

v3.17.11

Compare Source

Patch Changes

v3.17.10

Compare Source

Patch Changes
  • #​5368 3b26094 Thanks @​gcanti! - ## Annotation Behavior

    When you call .annotations on a schema, any identifier annotations that were previously set will now be removed. Identifiers are now always tied to the schema's ast reference (this was the intended behavior).

    Example

    import { JSONSchema, Schema } from "effect"
    
    const schema = Schema.URL
    
    console.log(JSON.stringify(JSONSchema.make(schema), null, 2))
    /*
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "$defs": {
        "URL": {
          "type": "string",
          "description": "a string to be decoded into a URL"
        }
      },
      "$ref": "#/$defs/URL"
    }
    */
    
    const annotated = Schema.URL.annotations({ description: "description" })
    
    console.log(JSON.stringify(JSONSchema.make(annotated), null, 2))
    /*
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "string",
      "description": "description"
    }
    */

v3.17.9

Compare Source

Patch Changes

v3.17.8

Compare Source

Patch Changes

v3.17.7

Compare Source

Patch Changes

v3.17.6

Compare Source

Patch Changes

v3.17.5

Compare Source

Patch Changes

v3.17.4

Compare Source

Patch Changes

v3.17.3

Compare Source

Patch Changes
  • #​5275 3504555 Thanks @​taylornz! - fix DateTime.makeZoned handling of DST transitions

  • #​5282 f6c7ca7 Thanks @​beezee! - Improve inference on Metric.trackSuccessWith for use in Effect.pipe(...)

  • #​5275 3504555 Thanks @​taylornz! - add DateTime.Disambiguation for handling DST edge cases

    Added four disambiguation strategies to DateTime.Zoned constructors for handling DST edge cases:

    • 'compatible' - Maintains backward compatibility
    • 'earlier' - Choose earlier time during ambiguous periods (default)
    • 'later' - Choose later time during ambiguous periods
    • 'reject' - Throw error for ambiguous times

v3.17.2

Compare Source

Patch Changes

v3.17.1

Compare Source

Patch Changes

v3.17.0

Compare Source

Minor Changes
  • #​4949 40c3c87 Thanks @​fubhy! - Added Random.fixed to create a version of the Random service with fixed
    values for testing.

  • #​4949 ed2c74a Thanks @​dmaretskyi! - Add Struct.entries function

  • #​4949 073a1b8 Thanks @​f15u! - Add Layer.mock

    Creates a mock layer for testing purposes. You can provide a partial
    implementation of the service, and any methods not provided will
    throw an UnimplementedError defect when called.

    import { Context, Effect, Layer } from "effect"
    
    class MyService extends Context.Tag("MyService")<
      MyService,
      {
        one: Effect.Effect<number>
        two(): Effect.Effect<number>
      }
    >() {}
    
    const MyServiceTest = Layer.mock(MyService, {
      two: () => Effect.succeed(2)
    })
  • #​4949 f382e99 Thanks @​KhraksMamtsov! - Schedule output has been added into CurrentIterationMetadata

  • #​4949 e8c7ba5 Thanks @​mikearnaldi! - Remove global state index by version, make version mismatch a warning message

  • #​4949 7e10415 Thanks @​devinjameson! - Array: add findFirstWithIndex function

  • #​4949 e9bdece Thanks @​vinassefranche! - Add HashMap.countBy

    import { HashMap } from "effect"
    
    const map = HashMap.make([1, "a"], [2, "b"], [3, "c"])
    const result = HashMap.countBy(map, (_v, key) => key % 2 === 1)
    console.log(result) // 2
  • #​4949 8d95eb0 Thanks @​tim-smart! - add Effect.ensure{Success,Error,Requirements}Type, for constraining Effect types

v3.16.17

Compare Source

Patch Changes

v3.16.16

Compare Source

Patch Changes

v3.16.15

Compare Source

Patch Changes
  • #​5222 15df9bf Thanks @​gcanti! - Schema.attachPropertySignature: simplify signature and fix parameter type to use Schema instead of SchemaClass

v3.16.14

Compare Source

Patch Changes
  • #​5213 f5dfabf Thanks @​gcanti! - Fix incorrect schema ID annotation in Schema.lessThanOrEqualToDate, closes #​5212

  • #​5192 17a5ea8 Thanks @​nikelborm! - Updated deprecated OTel Resource attributes names and values.

    Many of the attributes have undergone the process of deprecation not once, but twice. Most of the constants holding attribute names have been renamed. These are minor changes.

    Additionally, there were numerous changes to the attribute keys themselves. These changes can be considered major.

    In the @opentelemetry/semantic-conventions package, new attributes having ongoing discussion about them are going through a process called incubation, until a consensus about their necessity and form is reached. Otel team recommends devs to copy them directly into their code. Luckily, it's not necessary because all of the new attribute names and values came out of this process (some of them were changed again) and are now considered stable.

v3.16.13

Compare Source

Patch Changes

v3.16.12

Compare Source

Patch Changes

v3.16.11

Compare Source

Patch Changes

v3.16.10

Compare Source

Patch Changes

v3.16.9

Compare Source

Patch Changes

v3.16.8

Compare Source

Patch Changes

v3.16.7

Compare Source

Patch Changes

v3.16.6

Compare Source

Patch Changes

v3.16.5

Compare Source

Patch Changes

v3.16.4

Compare Source

Patch Changes

v3.16.3

Compare Source

Patch Changes

v3.16.2

Compare Source

Patch Changes

v3.16.1

Compare Source

Patch Changes

v3.16.0

Compare Source

Minor Changes
  • #​4891 ee0bd5d Thanks @​KhraksMamtsov! - Schedule.CurrentIterationMetadata has been added

    import { Effect, Schedule } from "effect"
    
    Effect.gen(function* () {
      const currentIterationMetadata = yield* Schedule.CurrentIterationMetadata
      //     ^? Schedule.IterationMetadata
    
      console.log(currentIterationMetadata)
    }).pipe(Effect.repeat(Schedule.recurs(2)))
    // {
    //   elapsed: Duration.zero,
    //   elapsedSincePrevious: Duration.zero,
    //   input: undefined,
    //   now: 0,
    //   recurrence: 0,
    //   start: 0
    // }
    // {
    //   elapsed: Duration.zero,
    //   elapsedSincePrevious: Duration.zero,
    //   input: undefined,
    //   now: 0,
    //   recurrence: 1,
    //   start: 0
    // }
    // {
    //   elapsed: Duration.zero,
    //   elapsedSincePrevious: Duration.zero,
    //   input: undefined,
    //   now: 0,
    //   recurrence: 2,
    //   start: 0
    // }
    
    Effect.gen(function* () {
      const currentIterationMetadata = yield* Schedule.CurrentIterationMetadata
    
      console.log(currentIterationMetadata)
    }).pipe(
      Effect.schedule(
        Schedule.intersect(Schedule.fibonacci("1 second"), Schedule.recurs(3))
      )
    )
    // {
    //   elapsed: Duration.zero,
    //   elapsedSincePrevious: Duration.zero,
    //   recurrence: 1,
    //   input: undefined,
    //   now: 0,
    //   start: 0
    // },
    // {
    //   elapsed: Duration.seconds(1),
    //   elapsedSincePrevious: Duration.seconds(1),
    //   recurrence: 2,
    //   input: undefined,
    //   now: 1000,
    //   start: 0
    // },
    // {
    //   elapsed: Duration.seconds(2),
    //   elapsedSincePrevious: Duration.seconds(1),
    //   recurrence: 3,
    //   input: undefined,
    //   now: 2000,
    //   start: 0
    // }
  • #​4891 5189800 Thanks @​vinassefranche! - Add HashMap.hasBy helper

    import { HashMap } from "effect"
    
    const hm = HashMap.make([1, "a"])
    HashMap.hasBy(hm, (value, key) => value === "a" && key === 1) // -> true
    HashMap.hasBy(hm, (value) => value === "b") // -> false
  • #​4891 58bfeaa Thanks @​jrudder! - Add round and sumAll to BigDecimal

  • #​4891 194d748 Thanks @​tim-smart! - add ExecutionPlan module

    A ExecutionPlan can be used with Effect.withExecutionPlan or Stream.withExecutionPlan, allowing you to provide different resources for each step of execution until the effect succeeds or the plan is exhausted.

    import { type AiLanguageModel } from "@&#8203;effect/ai"
    import type { Layer } from "effect"
    import { Effect, ExecutionPlan, Schedule } from "effect"
    
    declare const layerBad: Layer.Layer<AiLanguageModel.AiLanguageModel>
    declare const layerGood: Layer.Layer<AiLanguageModel.AiLanguageModel>
    
    const ThePlan = ExecutionPlan.make(
      {
        // First try with the bad layer 2 times with a 3 second delay between attempts
        provide: layerBad,
        attempts: 2,
        schedule: Schedule.spaced(3000)
      },
      // Then try with the bad layer 3 times with a 1 second delay between attempts
      {
        provide: layerBad,
        attempts: 3,
        schedule: Schedule.spaced(1000)
      },
      // Finally try with the good layer.
      //
      // If `attempts` is omitted, the plan will only attempt once, unless a schedule is provided.
      {
        provide: layerGood
      }
    )
    
    declare const effect: Effect.Effect<
      void,
      never,
      AiLanguageModel.AiLanguageModel
    >
    const withPlan: Effect.Effect<void> = Effect.withExecutionPlan(
      effect,
      ThePlan
    )
  • #​4891 918c9ea Thanks @​thewilkybarkid! - Add Array.removeOption and Chunk.removeOption

  • #​4891 9198e6f Thanks @​TylorS! - Add parameter support for Effect.Service

    This allows you to pass parameters to the effect & scoped Effect.Service
    constructors, which will also be reflected in the .Default layer.

    import type { Layer } from "effect"
    import { Effect } from "effect"
    
    class NumberService extends Effect.Service<NumberService>()("NumberService", {
      // You can now pass a function to the `effect` and `scoped` constructors
      effect: Effect.fn(function* (input: number) {
        return {
          get: Effect.succeed(`The number is: ${input}`)
        } as const
      })
    }) {}
    
    // Pass the arguments to the `Default` layer
    const CoolNumberServiceLayer: Layer.Layer<NumberService> =
      NumberService.Default(6942)
  • #​4891 2a370bf Thanks @​vinassefranche! - Add Iterable.countBy and Array.countBy

    import { Array, Iterable } from "effect"
    
    const resultArray = Array.countBy([1, 2, 3, 4, 5], (n) => n % 2 === 0)
    console.log(resultArray) // 2
    
    const resultIterable = resultIterable.countBy(
      [1, 2, 3, 4, 5],
      (n) => n % 2 === 0
    )
    console.log(resultIterable) // 2
  • #​4891 58ccb91 Thanks @​KhraksMamtsov! - The Config.port and Config.branded functions have been added.

    import { Brand, Config } from "effect"
    
    type DbPort = Brand.Branded<number, "DbPort">
    const DbPort = Brand.nominal<DbPort>()
    
    const dbPort: Config.Config<DbPort> = Config.branded(
      Config.port("DB_PORT"),
      DbPort
    )
    import { Brand, Config } from "effect"
    
    type Port = Brand.Branded<number, "Port">
    const Port = Brand.refined<Port>(
      (num) =>
        !Number.isNaN(num) && Number.isInteger(num) && num >= 1 && num <= 65535,
      (n) => Brand.error(`Expected ${n} to be an TCP port`)
    )
    
    const dbPort: Config.Config<Port> = Config.number("DB_PORT").pipe(
      Config.branded(Port)
    )
  • #​4891 fd47834 Thanks @​tim-smart! - return a proxy Layer from LayerMap service

    The new usage is:

    import { NodeRuntime } from "@&#8203;effect/platform-node"
    import { Context, Effect, FiberRef, Layer, LayerMap } from "effect"
    
    class Greeter extends Context.Tag("Greeter")<
      Greeter,
      {
        greet: Effect.Effect<string>
      }
    >() {}
    
    // create a service that wraps a LayerMap
    class GreeterMap extends LayerMap.Service<GreeterMap>()("GreeterMap", {
      // define the lookup function for the layer map
      //
      // The returned Layer will be used to provide the Greeter service for the
      // given name.
      lookup: (name: string) =>
        Layer.succeed(Greeter, {
          greet: Effect.succeed(`Hello, ${name}!`)
        }),
    
      // If a layer is not used for a certain amount of time, it can be removed
      idleTimeToLive: "5 seconds",
    
      // Supply the dependencies for the layers in the LayerMap
      dependencies: []
    }) {}
    
    // usage
    const program: Effect.Effect<void, never, GreeterMap> = Effect.gen(
      function* () {
        // access and use the Greeter service
        const greeter = yield* Greeter
        yield* Effect.log(yield* greeter.greet)
      }
    ).pipe(
      // use the GreeterMap service to provide a variant of the Greeter service
      Effect.provide(GreeterMap.get("John"))
    )
    
    // run the program
    program.pipe(Effect.provide(GreeterMap.Default), NodeRuntime.runMain)

v3.15.5

Compare Source

Patch Changes

v3.15.4

Compare Source

Patch Changes

v3.15.3

Compare Source

Patch Changes

v3.15.2

Compare Source

Patch Changes

v3.15.1

Compare Source

Patch Changes

v3.15.0

Compare Source

Minor Changes

v3.14.22

Compare Source

Patch Changes
  • #​4847 24a9ebb Thanks @​gcanti! - Schema: TaggedError no longer crashes when the message field is explicitly defined.

    If you define a message field in your schema, TaggedError will no longer add its own message getter. This avoids a stack overflow caused by infinite recursion.

    Before

    import { Schema } from "effect"
    
    class Todo extends Schema.TaggedError<Todo>()("Todo", {
      message: Schema.optional(Schema.String)
    }) {}
    
    // ❌ Throws "Maximum call stack size exceeded"
    console.log(Todo.make({}))

    After

    // ✅ Works correctly
    console.log(Todo.make({}))

v3.14.21

Compare Source

Patch Changes

v3.14.20

Compare Source

Patch Changes
  • #​4832 17e2f30 Thanks @​gcanti! - JSONSchema: respect annotations on declarations.

    Previously, annotations added with .annotations(...) on Schema.declare(...) were not included in the generated JSON Schema output.

    Before

    import { JSONSchema, Schema } from "effect"
    
    class MyType {}
    
    const schema = Schema.declare<MyType>((x) => x instanceof MyType, {
      jsonSchema: {
        type: "my-type"
      }
    }).annotations({
      title: "My Title",
      description: "My Description"
    })
    
    console.log(JSON.stringify(JSONSchema.make(schema), null, 2))
    /*
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "type": "my-type"
    }
    */

    After

    import { JSONSchema, Schema } from "effect"
    
    class MyType {}
    
    const schema = Schema.declare<MyType>((x) => x instanceof MyType, {
      jsonSchema: {
        type: "my-type"
      }
    }).annotations({
      title: "My Title",
      description: "My Description"
    })
    
    console.log(JSON.stringify(JSONSchema.make(schema), null, 2))
    /*
    {
      "$schema": "http://json-schema.org/draft-07/schema#",
      "description": "My Description",
      "title": "My Title",
      "type": "my-type"
    }
    */

v3.14.19

Compare Source

Patch Changes

v3.14.18

Compare Source

Patch Changes

v3.14.17

Compare Source


Configuration

📅 Schedule: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate renovate bot added renovate upgrade Any kind of dependency updates labels Apr 16, 2024
@renovate
Copy link
Contributor Author

renovate bot commented Apr 16, 2024

⚠ Artifact update problem

Renovate failed to update an artifact related to this branch. You probably do not want to merge this PR as-is.

♻ Renovate will retry this branch, including artifacts, only when one of the following happens:

  • any of the package files in this branch needs updating, or
  • the branch becomes conflicted, or
  • you click the rebase/retry checkbox if found above, or
  • you rename this PR's title to start with "rebase!" to trigger it manually

The artifact failure details are included below:

File name: package-lock.json
npm error code ERESOLVE
npm error ERESOLVE could not resolve
npm error
npm error While resolving: @effect/[email protected]
npm error Found: [email protected]
npm error node_modules/effect
npm error   effect@"3.1.3" from the root project
npm error
npm error Could not resolve dependency:
npm error peer effect@"^2.1.1" from @effect/[email protected]
npm error node_modules/@effect/schema
npm error   @effect/schema@"0.60.4" from the root project
npm error
npm error Conflicting peer dependency: [email protected]
npm error node_modules/effect
npm error   peer effect@"^2.1.1" from @effect/[email protected]
npm error   node_modules/@effect/schema
npm error     @effect/schema@"0.60.4" from the root project
npm error
npm error Fix the upstream dependency conflict, or retry
npm error this command with --force or --legacy-peer-deps
npm error to accept an incorrect (and potentially broken) dependency resolution.
npm error
npm error
npm error For a full report see:
npm error /tmp/renovate/cache/others/npm/_logs/2024-05-08T22_22_18_081Z-eresolve-report.txt

npm error A complete log of this run can be found in: /tmp/renovate/cache/others/npm/_logs/2024-05-08T22_22_18_081Z-debug-0.log

@renovate renovate bot force-pushed the renovate/effect-3.x branch 8 times, most recently from ac64789 to 5c44085 Compare April 25, 2024 04:19
@renovate renovate bot force-pushed the renovate/effect-3.x branch 10 times, most recently from 9d2cf0f to d4fa257 Compare May 2, 2024 22:37
@renovate renovate bot force-pushed the renovate/effect-3.x branch 9 times, most recently from b3879b8 to a7c2703 Compare May 8, 2024 22:22
@renovate renovate bot force-pushed the renovate/effect-3.x branch 11 times, most recently from 6e69cce to 818be06 Compare October 10, 2025 02:31
@renovate renovate bot force-pushed the renovate/effect-3.x branch 9 times, most recently from 9dc62f9 to a5be583 Compare October 17, 2025 08:59
@renovate renovate bot force-pushed the renovate/effect-3.x branch 6 times, most recently from 8466cbf to 042cd11 Compare October 25, 2025 01:59
@renovate renovate bot force-pushed the renovate/effect-3.x branch 2 times, most recently from a207697 to 5f66cf5 Compare October 28, 2025 18:01
@renovate renovate bot force-pushed the renovate/effect-3.x branch from 5f66cf5 to aa9982a Compare October 28, 2025 23:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

renovate upgrade Any kind of dependency updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant