diff options
-rw-r--r-- | .envrc | 2 | ||||
-rw-r--r-- | .gitignore | 35 | ||||
-rw-r--r-- | .ocamlformat | 2 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | bin/dune | 5 | ||||
-rw-r--r-- | bin/main.ml | 19 | ||||
-rw-r--r-- | dune-project | 27 | ||||
-rw-r--r-- | flake.lock | 189 | ||||
-rw-r--r-- | flake.nix | 66 | ||||
-rw-r--r-- | lib/activitypub/activitypub.ml | 5 | ||||
-rw-r--r-- | lib/activitypub/common.ml | 47 | ||||
-rw-r--r-- | lib/activitypub/constants.ml | 49 | ||||
-rw-r--r-- | lib/activitypub/decode.ml | 352 | ||||
-rw-r--r-- | lib/activitypub/dune | 3 | ||||
-rw-r--r-- | lib/activitypub/encode.ml | 303 | ||||
-rw-r--r-- | lib/activitypub/readme.md | 5 | ||||
-rw-r--r-- | lib/activitypub/types.ml | 245 | ||||
-rw-r--r-- | lib/dune | 18 | ||||
-rw-r--r-- | lib/http_date.ml | 37 | ||||
-rw-r--r-- | lib/parser.ml | 75 | ||||
-rw-r--r-- | lib/sig.ml | 167 | ||||
-rw-r--r-- | lib/user.ml | 31 | ||||
-rw-r--r-- | package-defs.json | 1 | ||||
-rwxr-xr-x | scripts/add-dependency.sh | 17 | ||||
-rwxr-xr-x | scripts/run-test-watch.sh | 1 | ||||
-rwxr-xr-x | scripts/run-watch.sh | 3 | ||||
-rw-r--r-- | test/ann_bloop.ml | 0 | ||||
-rw-r--r-- | test/dune | 2 |
28 files changed, 1712 insertions, 0 deletions
@@ -0,0 +1,2 @@ +git config --local core.hooksPath $PWD/.githooks +use flake . diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4ba15f1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,35 @@ +# Dune +_build/ +.merlin +*.install +result + +# opam +_opam/ + +# npm +node_modules/ +example/*/package-lock.json + +.wormhole.opam +# esy +_esy/ +esy.lock + +# Release script +dream-*.gz +dream-*/ + +# Bisect_ppx +_coverage/ + +# Humans +scratch/ + +# Editors +.vscode/ +*.swp +.direnv/* + +private.pem +*.opam diff --git a/.ocamlformat b/.ocamlformat new file mode 100644 index 0000000..3998b54 --- /dev/null +++ b/.ocamlformat @@ -0,0 +1,2 @@ +profile = janestreet +parse-docstrings = true diff --git a/README.md b/README.md new file mode 100644 index 0000000..3c15303 --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# Bloop Ann + +## Prerequisites + +- Nix +- Direnv diff --git a/bin/dune b/bin/dune new file mode 100644 index 0000000..62d69ee --- /dev/null +++ b/bin/dune @@ -0,0 +1,5 @@ +(executable + (public_name ann_bloop) + (name main) + (libraries ann_bloop uri dream) + (preprocess (pps lwt_ppx ppx_yojson_conv ppx_inline_test))) diff --git a/bin/main.ml b/bin/main.ml new file mode 100644 index 0000000..2ed3595 --- /dev/null +++ b/bin/main.ml @@ -0,0 +1,19 @@ +open Ann_bloop + +let () = + let port = + Sys.getenv_opt "PORT" |> Option.map int_of_string + |> Option.value ~default:8080 + in + let env = Sys.getenv_opt "ENV" |> Option.value ~default:"PROD" in + let disable_auth = + Sys.getenv_opt "DISABLE_AUTH" |> Option.value ~default:"false" + in + let interface = if env = "DEV" then "localhost" else "0.0.0.0" in + Dream.run ~port ~interface @@ Dream.logger + @@ Dream.router + [ + Dream.get "/actor" (fun _ -> + Dream.log "Sending actor"; + Dream.html "Hello world!") + ] diff --git a/dune-project b/dune-project new file mode 100644 index 0000000..dc732ee --- /dev/null +++ b/dune-project @@ -0,0 +1,27 @@ +(lang dune 3.11) + +(name ann_bloop) + +(generate_opam_files true) + +(source + (github username/reponame)) + +(authors "Marc Coquand") + +(maintainers "Marc Coquand") + +(license AGPL-3.0-only) + +(documentation https://url/to/documentation) + +(package + (name ann_bloop) + (synopsis "A short synopsis") + (description "A longer description") + (depends ocaml dune dream ppx_yojson_conv crunch cohttp lwt_ppx cohttp-lwt-unix containers calendar ptime mirage-crypto-rng mirage-crypto-rng-lwt ppx_inline_test ppx_deriving decoders-yojson) + (tags + (topics "to describe" your project))) + + +; See the complete stanza docs at https://dune.readthedocs.io/en/stable/dune-files.html#dune-project diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..7560b91 --- /dev/null +++ b/flake.lock @@ -0,0 +1,189 @@ +{ + "nodes": { + "flake-compat": { + "flake": false, + "locked": { + "lastModified": 1627913399, + "narHash": "sha256-hY8g6H2KFL8ownSiFeMOjwPC8P0ueXpCVEbxgda3pko=", + "owner": "edolstra", + "repo": "flake-compat", + "rev": "12c64ca55c1014cdc1b16ed5a804aa8576601ff2", + "type": "github" + }, + "original": { + "owner": "edolstra", + "repo": "flake-compat", + "type": "github" + } + }, + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1701680307, + "narHash": "sha256-kAuep2h5ajznlPMD9rnQyffWG8EM/C73lejGofXvdM8=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "4022d587cbbfd70fe950c1e2083a02621806a725", + "type": "github" + }, + "original": { + "id": "flake-utils", + "type": "indirect" + } + }, + "flake-utils_2": { + "locked": { + "lastModified": 1638122382, + "narHash": "sha256-sQzZzAbvKEqN9s0bzWuYmRaA03v40gaJ4+iL1LXjaeI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "74f7e4319258e287b0f9cb95426c9853b282730b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "mirage-opam-overlays": { + "flake": false, + "locked": { + "lastModified": 1661959605, + "narHash": "sha256-CPTuhYML3F4J58flfp3ZbMNhkRkVFKmBEYBZY5tnQwA=", + "owner": "dune-universe", + "repo": "mirage-opam-overlays", + "rev": "05f1c1823d891ce4d8adab91f5db3ac51d86dc0b", + "type": "github" + }, + "original": { + "owner": "dune-universe", + "repo": "mirage-opam-overlays", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1703117891, + "narHash": "sha256-E7p42UknHFHoBmHz+xuqK6S0gvKrvMWoN28ld1iGbAc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "b7976f22c685f9c6e28be644806f0f1901813203", + "type": "github" + }, + "original": { + "owner": "NixOS", + "repo": "nixpkgs", + "type": "github" + } + }, + "opam-nix": { + "inputs": { + "flake-compat": "flake-compat", + "flake-utils": "flake-utils_2", + "mirage-opam-overlays": "mirage-opam-overlays", + "nixpkgs": [ + "nixpkgs" + ], + "opam-overlays": "opam-overlays", + "opam-repository": [ + "opam-repository" + ], + "opam2json": "opam2json" + }, + "locked": { + "lastModified": 1702988812, + "narHash": "sha256-XdGK59SJsZZU9eeulWxopzdS3PZSbRls7i53KEJZ60A=", + "owner": "tweag", + "repo": "opam-nix", + "rev": "a2c8f7d640f1dcb92f036044f13eb9135f6db474", + "type": "github" + }, + "original": { + "owner": "tweag", + "repo": "opam-nix", + "type": "github" + } + }, + "opam-overlays": { + "flake": false, + "locked": { + "lastModified": 1654162756, + "narHash": "sha256-RV68fUK+O3zTx61iiHIoS0LvIk0E4voMp+0SwRg6G6c=", + "owner": "dune-universe", + "repo": "opam-overlays", + "rev": "c8f6ef0fc5272f254df4a971a47de7848cc1c8a4", + "type": "github" + }, + "original": { + "owner": "dune-universe", + "repo": "opam-overlays", + "type": "github" + } + }, + "opam-repository": { + "flake": false, + "locked": { + "lastModified": 1703021868, + "narHash": "sha256-7E9uT7tc6qcJrr/oTWY3wgtQawM4zymtyn8k0hCwjko=", + "owner": "ocaml", + "repo": "opam-repository", + "rev": "1a01639f743228bcd2b03a3a610c8c2b88bbd944", + "type": "github" + }, + "original": { + "owner": "ocaml", + "repo": "opam-repository", + "type": "github" + } + }, + "opam2json": { + "inputs": { + "nixpkgs": [ + "opam-nix", + "nixpkgs" + ] + }, + "locked": { + "lastModified": 1671540003, + "narHash": "sha256-5pXfbUfpVABtKbii6aaI2EdAZTjHJ2QntEf0QD2O5AM=", + "owner": "tweag", + "repo": "opam2json", + "rev": "819d291ea95e271b0e6027679de6abb4d4f7f680", + "type": "github" + }, + "original": { + "owner": "tweag", + "repo": "opam2json", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "opam-nix": "opam-nix", + "opam-repository": "opam-repository" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..20b8532 --- /dev/null +++ b/flake.nix @@ -0,0 +1,66 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs"; + opam-nix.url = "github:tweag/opam-nix"; + opam-repository = { + url = "github:ocaml/opam-repository"; + flake = false; + }; + opam-nix.inputs.opam-repository.follows = "opam-repository"; + opam-nix.inputs.nixpkgs.follows = "nixpkgs"; + }; + + outputs = { self, nixpkgs, opam-nix, flake-utils, ... }: + flake-utils.lib.eachDefaultSystem (system: + let + system = "x86_64-linux"; + pkgs = nixpkgs.legacyPackages.${system}; + inherit (opam-nix.lib.${system}) + buildOpamProject + materializedDefsToScope + materializeOpamProject'; + package = "ann_bloop"; + devPackagesQuery = { + ocaml-lsp-server = "*"; + ocamlformat = "*"; + # 1.9.6 fails to build + ocamlfind = "1.9.5"; + utop = "*"; + }; + query = { + ocaml-base-compiler = "*"; + }; + overlay = final: prev: { + "${package}" = prev.${package}.overrideAttrs (_: { + # override derivation attributes, e.g. add additional dependacies + buildInputs = [ + pkgs."gmp" + pkgs."libev" + pkgs."openssl" + ]; + }); + }; + devBuildInputs = [ pkgs.ocamlPackages.ocamlformat ]; + resolved-scope = + let scope = buildOpamProject { } package ./. query; + in scope.overrideScope' overlay; + materialized-scope = + let scope = materializedDefsToScope + { sourceMap.${package} = ./.; } ./package-defs.json; + in scope.overrideScope' overlay; + in rec { + packages = { + resolved = resolved-scope; + materialized = materialized-scope; + # to generate: + # cat $(nix eval .#package-defs --raw) > package-defs.json + package-defs = materializeOpamProject' { } ./. query; + }; + defaultPackage = packages.materialized.${package}; + devShells.default = pkgs.mkShell { + inputsFrom = [ defaultPackage ]; + buildInputs = devBuildInputs; + }; + } + ); +} diff --git a/lib/activitypub/activitypub.ml b/lib/activitypub/activitypub.ml new file mode 100644 index 0000000..511b4a3 --- /dev/null +++ b/lib/activitypub/activitypub.ml @@ -0,0 +1,5 @@ +module Common = Common +module Constants = Constants +module Types = Types +module Encode = Encode +module Decode = Decode diff --git a/lib/activitypub/common.ml b/lib/activitypub/common.ml new file mode 100644 index 0000000..59c7099 --- /dev/null +++ b/lib/activitypub/common.ml @@ -0,0 +1,47 @@ +module D = Decoders_yojson.Safe.Decode + +let timestamp = + let open D in + let* time = string in + match Ptime.of_rfc3339 time |> Ptime.rfc3339_error_to_msg with + | Ok (t, _, _) -> succeed t + | Error `Msg err -> fail err + +let singleton_or_list dec = + D.(one_of ["singleton", (dec >|= fun v -> [v]); + "list", list dec; + "null", null >|= fun () -> []]) + +let lossy_list_of dec = + let open D in + list (one_of ["known", (dec >|= fun v -> `Value v); "unknown", value >|= fun v -> `Raw v]) + + +let constant ?msg target = + let open D in + let* str = string in + if String.equal str target + then succeed () + else match msg with + | None -> fail (Printf.sprintf "expected %s received %s" target str) + | Some msg -> fail (Printf.sprintf msg str) + +let field_or_default field' decoder default = + let open D in + let+ field = field_opt field' decoder in + Option.value ~default field + +let list_ignoring_unknown ty = + let open D in + list (maybe ty) >|= fun v -> List.filter_map Fun.id v + +let items obj = + let open D in + one_of [ + ("ordered items", + let* items = field "orderedItems" (list obj) in + succeed (true, items)); + "items", + let* items = field "items" (list obj) in + succeed (false, items) + ] diff --git a/lib/activitypub/constants.ml b/lib/activitypub/constants.ml new file mode 100644 index 0000000..0488335 --- /dev/null +++ b/lib/activitypub/constants.ml @@ -0,0 +1,49 @@ +open Containers + +module ContentType = struct + let ld_json_activity_streams = "application/ld+json; profile=\"https://www.w3.org/ns/activitystreams\"" + + let xrd_xml = "application/xrd+xml" + let ld_json = "application/ld+json" + let activity_json = "application/activity+json" + let plain_json = "application/json" + let html = "text/html" + let any = "*/*" + + let content_types = [ + ld_json_activity_streams, `JSON; + ld_json, `JSON; + activity_json, `JSON; + plain_json, `JSON; + html, `HTML; + any, `HTML; + ] + + let of_string content_type = + List.find_opt + (fun (str, _) -> + String.prefix ~pre:str content_type) content_types + |> Option.map snd + + +end + +module Webfinger = struct + let json_rd = "application/jrd+json" + + let self_rel = "self" + let ostatus_rel = "http://ostatus.org/schema/1.0/subscribe" + let profile_page = "http://webfinger.net/rel/profile-page" +end + +module ActivityStreams = struct + + let public = "https://www.w3.org/ns/activitystreams#Public" + + let context : string * Yojson.Safe.t = + "@context", `List [ + `String "https://www.w3.org/ns/activitystreams"; + `String "https://w3id.org/security/v1" + ] + +end diff --git a/lib/activitypub/decode.ml b/lib/activitypub/decode.ml new file mode 100644 index 0000000..4074e68 --- /dev/null +++ b/lib/activitypub/decode.ml @@ -0,0 +1,352 @@ +open Containers +open Common + +let decode_string enc vl = D.decode_string enc vl |> Result.map_err D.string_of_error + +let id = D.(one_of ["string", string; "id", field "id" string]) + +let ordered_collection_page obj = + let open D in + let* () = field "type" @@ constant ~msg:"Expected OrderedCollectionPage (received %s)" "OrderedCollectionPage" + and* id = field "id" string + and* next = field_opt "next" id + and* prev = field_opt "prev" id + and* part_of = field_opt "partOf" string + and* total_items = field_opt "totalItems" int + and* (is_ordered, items) = items obj in + succeed ({id; next; prev; part_of; total_items; is_ordered; items}: _ Types.ordered_collection_page) + +let ordered_collection obj = + let open D in + let* () = field "type" @@ constant ~msg:"Expected OrderedCollection (received %s)" "OrderedCollection" + and* id = field_opt "id" string + and* total_items = field "totalItems" int + and* contents = + one_of [ + "items", map (fun v -> `Items v) (items obj); + "first", map (fun v -> `First v) (field "first" (ordered_collection_page obj)) + ] in + succeed ({id; total_items; contents}: _ Types.ordered_collection) + +let mention = + let open D in + let* () = field "type" @@ constant ~msg:"expected Mention (received %s)" "Mention" + and* href = field "href" string + and* name = field "name" string in + succeed ({ty=`Mention; href;name} : Types.tag) + +let hashtag = + let open D in + let* () = field "type" @@ constant ~msg:"expected Hashtag (received %s)" "Hashtag" + and* href = field "href" string + and* name = field "name" string in + succeed ({ty=`Hashtag; href;name}: Types.tag) + +let tag = + let open D in + let* ty = field "type" string in + match ty with + | "Mention" -> mention + | "Hashtag" -> hashtag + | _ -> fail (Printf.sprintf "unknown tag %s" ty) + +let undo obj = + let open D in + let* () = field "type" @@ constant ~msg:"expected Undo (received %s)" "Undo" + and* id = field "id" string + and* actor = field "actor" id + and* published = field_opt "published" timestamp + and* obj = field "object" obj + and* raw = value in + succeed ({id;published;actor;obj;raw}: _ Types.undo) + +let like = + let open D in + let* () = field "type" @@ constant ~msg:"expected Like (received %s)" "Like" + and* id = field "id" string + and* actor = field "actor" id + and* published = field_opt "published" timestamp + and* obj = field "object" id + and* raw = value in + succeed ({id; actor; published; obj; raw}: Types.like) + +let tombstone = + let open D in + let* () = field "type" @@ constant ~msg:"expected Tombstone (received %s)" "Tombstone" + and* id = field "id" string in + succeed id + +let delete obj = + let open D in + let* () = field "type" @@ constant ~msg:"expected Delete (received %s)" "Delete" + and* id = field "id" string + and* actor = field "actor" id + and* published = field_opt "published" timestamp + and* obj = field "object" obj + and* raw = value in + succeed ({id;published;actor;obj;raw}: _ Types.delete) + +let block = + let open D in + let* () = field "type" @@ constant ~msg:"expected Block (received %s)" "Block" + and* id = field "id" string + and* obj = field "object" string + and* published = field_opt "published" timestamp + and* actor = field "actor" id + and* raw = value in + succeed ({id;published;obj;actor;raw}: Types.block) + +let accept obj = + let open D in + let* () = field "type" @@ constant ~msg:"expected Accept (received %s)" "Accept" + and* id = field "id" string + and* actor = field "actor" id + and* published = field_opt "published" timestamp + and* obj = field "object" obj + and* raw = value in + succeed ({id;published;actor;obj;raw}: _ Types.accept) + +let public_key = + let open D in + let* id = field "id" string + and* owner = field "owner" string + and* pem = field "publicKeyPem" string in + succeed ({id;owner;pem}: Types.public_key) + +let attachment = + let open D in + let* media_type = field_opt "mediaType" string + and* name = field_opt "name" string + and* type_ = field_opt "type" string + and* url = field "url" string in + succeed ({media_type;name;type_;url}: Types.attachment) + + +let person = + let open D in + let* () = field "type" @@ constant ~msg:"expected Person (received %s)" "Person" + and* id = field "id" string + and* name = field_opt "name" string + and* url = field_or_default "url" (nullable string) None + and* preferred_username = field_opt "preferredUsername" string + and* inbox = field "inbox" string + and* outbox = field "outbox" string + and* summary = field_opt "summary" string + and* public_key = field "publicKey" public_key + and* manually_approves_followers = + field_or_default "manuallyApprovesFollowers" bool false + and* discoverable = field_or_default "discoverable" bool false + and* followers = field_opt "followers" string + and* following = field_opt "following" string + and* icon = maybe (at ["icon";"url"] string) + and* raw = value in + succeed ({ + id; + name; + url; + + preferred_username; + + inbox; + outbox; + + summary; + + public_key; + + manually_approves_followers; + + discoverable; + followers; + following; + icon; + raw; + }: Types.person) + +let note = + let open D in + let* () = field "type" @@ constant ~msg:"expected Note (received %s)" "Note" + and* id = field "id" string + and* actor = one_of ["actor", field "actor" id; "attributed_to", field "attributedTo" id] + and* attachment = field_or_default "attachment" (singleton_or_list attachment) [] + and* to_ = field "to" (singleton_or_list string) + and* in_reply_to = field_or_default "inReplyTo" (nullable string) None + and* cc = field_or_default "cc" (singleton_or_list string) [] + and* content = field "content" string + and* source = field_opt "source" + (one_of ["string", string; "multi-encode", field "content" string]) + and* summary = field_or_default "summary" (nullable string) None + and* sensitive = field_or_default "sensitive" (nullable bool) None + and* published = field_opt "published" timestamp + and* tags = field_or_default "tag" (lossy_list_of tag) [] + and* raw = value in + succeed ({ id; actor; attachment; in_reply_to; to_; cc; + sensitive=Option.value ~default:false sensitive; + content; source; summary; tags; published; raw }: Types.note) + +let follow = + let open D in + let* () = field "type" @@ constant ~msg:"expected create object (received %s)" "Follow" + and* actor = field "actor" id + and* cc = field_or_default "cc" (singleton_or_list string) [] + and* to_ = field_or_default "to" (singleton_or_list string) [] + and* id = field "id" string + and* object_ = field "object" id + and* state = field_opt "state" (string >>= function "pending" -> succeed `Pending + | "cancelled" -> succeed `Cancelled + | _ -> fail "unknown status") + and* raw = value in + succeed ({actor; cc; to_; id; object_; state; raw}: Types.follow) + +let announce obj = + let open D in + let* () = field "type" @@ constant ~msg:"expected create object (received %s)" "Announce" + and* actor = field "actor" id + and* id = field "id" string + and* published = field_opt "published" timestamp + and* to_ = field "to" (singleton_or_list string) + and* cc = field_or_default "cc" (singleton_or_list string) [] + and* obj = field "object" obj + and* raw = value in + succeed ({id; published; actor; to_; cc; obj; raw}: _ Types.announce) + +let create obj = + let open D in + let* () = field "type" @@ constant ~msg:"expected create object (received %s)" "Create" + and* id = field "id" string + and* actor = field "actor" id + and* direct_message = field_or_default "direct" bool false + and* published = field_opt "published" timestamp + and* to_ = field_or_default "to" (singleton_or_list string) [] + and* cc = field_or_default "cc" (singleton_or_list string) [] + and* obj = field "object" obj + and* raw = value in + + succeed ({ + id; actor; published; + to_; cc; + direct_message; + obj; + raw; + }: _ Types.create) + +let core_obj () = + let open D in + let* ty = field_opt "type" string in + match ty with + | Some "Person" -> person >|= fun v -> `Person v + | Some "Follow" -> follow >|= fun v -> `Follow v + | Some "Note" -> note >|= fun v -> `Note v + | Some "Block" -> block >|= fun v -> `Block v + | Some "Like" -> like >|= fun v -> `Like v + | None -> string >|= fun v -> `Link v + | Some ev -> fail ("unsupported event" ^ ev) + +let core_obj = core_obj () + +let event (enc: Types.core_obj D.decoder) : Types.obj D.decoder = + let open D in + let* ty = field "type" string in + match ty with + | "Create" -> create enc >|= fun v -> `Create v + | "Accept" -> accept enc >|= fun v -> `Accept v + | "Undo" -> undo enc >|= fun v -> `Undo v + | "Delete" -> delete enc >|= fun v -> `Delete v + | "Announce" -> announce enc >|= fun v -> `Announce v + | _ -> fail "unsupported event" + +let obj : Types.obj D.decoder = + D.one_of [ + "core_obj", core_obj; + "core_obj event", (event core_obj) + ] + +module Webfinger = struct + + let ty = + let open D in + string >>= function + | str when String.prefix ~pre:Constants.ContentType.html str -> + succeed `Html + | str when String.prefix ~pre:Constants.ContentType.plain_json str -> + succeed `Json + | str when String.prefix ~pre:Constants.ContentType.activity_json str -> + succeed `ActivityJson + | str when String.prefix ~pre:Constants.ContentType.ld_json_activity_streams str -> + succeed `ActivityJsonLd + | _ -> + fail "unsupported self link type" + + let self = + let open D in + let* ty = field "type" ty + and* href = field "href" string in + succeed @@ Types.Webfinger.Self (ty, href) + + let profile_page = + let open D in + let* ty = field "type" ty + and* href = field "href" string in + succeed @@ Types.Webfinger.ProfilePage (ty, href) + + let ostatus_subscribe = + let open D in + let* template = field "template" string in + succeed @@ Types.Webfinger.OStatusSubscribe template + + let link = + let open D in + let* rel = field "rel" string in + match rel with + | "self" -> self + | str when String.equal str Constants.Webfinger.ostatus_rel -> + ostatus_subscribe + | str when String.equal str Constants.Webfinger.profile_page -> + profile_page + | _ -> fail "unsupported link relation" + + let query_result = + let open D in + let* subject = field "subject" string + and* aliases = field "aliases" (list string) + and* links = field "links" (list_ignoring_unknown link) in + + succeed Types.Webfinger.{subject;aliases;links} + +end + +module Nodeinfo = struct + + let software = + let open D in + let* name = field "name" string + and* version = field "version" string in + succeed @@ Types.Nodeinfo.{name;version} + + let usage_users = + let open D in + let* total = field_or_default "total" int 0 + and* active_month = field_or_default "activeMonth" int 0 + and* active_half_year = field_or_default "activeHalfyear" int 0 in + succeed @@ Types.Nodeinfo.{total; active_month; active_half_year} + + let usage = + let open D in + let* users = field "users" usage_users + and* local_posts = field_or_default "localPosts" int 0 in + succeed @@ Types.Nodeinfo.{users; local_posts} + + let t = + let open D in + let* software = field "software" software + and* protocols = field_or_default "protocols" (list string) [] + and* inbound_services = field_or_default "services" (field_or_default "inbound" (list string) []) [] + and* outbound_services = field_or_default "services" (field_or_default "outbound" (list string) []) [] + and* usage = field "usage" usage + and* open_registrations = field_or_default "openRegistrations" bool false + and* metadata = field_opt "metadata" value + and* raw = value in + succeed @@ Types.Nodeinfo.{software;protocols;inbound_services;outbound_services;usage;open_registrations;metadata;raw} + + +end diff --git a/lib/activitypub/dune b/lib/activitypub/dune new file mode 100644 index 0000000..9222a82 --- /dev/null +++ b/lib/activitypub/dune @@ -0,0 +1,3 @@ +(library (name activitypub) + (preprocess (pps ppx_deriving.std)) + (libraries containers uri yojson decoders decoders-yojson ptime)) diff --git a/lib/activitypub/encode.ml b/lib/activitypub/encode.ml new file mode 100644 index 0000000..2b64e76 --- /dev/null +++ b/lib/activitypub/encode.ml @@ -0,0 +1,303 @@ +module E = Decoders_yojson.Safe.Encode + + +let (<:) = function + | (_, None) -> fun _ -> [] + | (field, Some vl) -> fun ty -> [field, ty vl] +let (@) field vl = (field, Some vl) +let (@?) field vl = (field, vl) + +let ptime time = E.string (Ptime.to_rfc3339 ~tz_offset_s:0 time) +let obj ls = E.obj @@ List.flatten ls +let ap_obj ty ls = + E.obj (Constants.ActivityStreams.context :: ("type", E.string ty) :: List.flatten ls) + +let or_raw conv = function + | `Raw v -> v + | `Value v -> conv v + +(** * Collections *) +let ordered_collection_page enc + ({ id; prev; next; is_ordered; items; part_of; total_items }: + _ Types.ordered_collection_page) = + ap_obj "OrderedCollectionPage" [ + "id" @ id <: E.string; + "next" @? next <: E.string; + "prev" @? prev <: E.string; + "partOf" @? part_of <: E.string; + "totalItems" @? total_items <: E.int; + (match is_ordered with + | true -> "orderedItems" + | false -> "items") @ items <: E.list enc + ] + +let ordered_collection enc + ({ id; total_items; contents }: _ Types.ordered_collection) = + ap_obj "OrderedCollection" [ + "id" @? id <: E.string; + "totalItems" @ total_items <: E.int; + match contents with + | `First page -> "first" @ page <: ordered_collection_page enc + | `Items (true, items) -> "orderedItems" @ items <: E.list enc + | `Items (false, items) -> "items" @ items <: E.list enc + ] + +(** * Events *) + +let create enc ({ id; actor; published; to_; cc; direct_message; obj; raw=_ }: + _ Types.create) = + ap_obj "Create" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + "to" @ to_ <: E.(list string); + "cc" @ cc <: E.(list string); + "directMessage" @ direct_message <: E.bool; + "object" @ obj <: enc; + ] + +let announce enc ({ id; actor; published; to_; cc; obj; raw=_ } : _ Types.announce) = + ap_obj "Announce" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + "to" @ to_ <: E.(list string); + "cc" @ cc <: E.(list string); + "object" @ obj <: enc; + ] + +let accept enc ({ id; actor; published; obj; raw=_ } : _ Types.accept) = + ap_obj "Accept" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + "object" @ obj <: enc; + ] + +let undo enc ({ id; actor; published; obj; raw=_ } : _ Types.undo) = + ap_obj "Undo" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + "object" @ obj <: enc; + ] + +let delete enc ({ id; actor; published; obj; raw=_ } : _ Types.delete) = + ap_obj "Delete" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + "object" @ obj <: enc; + ] + +(** * Objects *) + +let public_key (key: Types.public_key) = + obj [ + "id" @ key.id <: E.string; + "owner" @ key.owner <: E.string; + "publicKeyPem" @ key.pem <: E.string; + ] + +let icon (url: string) = + obj [ + "type" @ "Image" <: E.string; + "url" @ url <: E.string; + ] + +let person ({ id; name; url; inbox; outbox; + preferred_username; summary; + manually_approves_followers; + discoverable; followers; following; + public_key=key; icon=i; raw=_ }: Types.person) = + ap_obj "Person" [ + + "id" @ id <: E.string; + + "name" @? name <: E.string; + "url" @? url <: E.string; + + "preferredUsername" @? preferred_username <: E.string; + + "inbox" @ inbox <: E.string; + "outbox" @ outbox <: E.string; + + "summary" @? summary <: E.string; + + "publicKey" @ key <: public_key; + + "manuallyApprovesFollowers" @ manually_approves_followers <: E.bool; + + "discoverable" @ discoverable <: E.bool; + + "followers" @? followers <: E.string; + "following" @? following <: E.string; + + "icon" @? i <: icon; + ] + +let state = function + `Pending -> E.string "pending" + | `Cancelled -> E.string "cancelled" + + +let follow ({ id; actor; cc; object_; to_; state=st; raw=_ }: Types.follow) = + ap_obj "Follow" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "to" @ to_ <: E.list E.string; + "cc" @ cc <: E.list E.string; + "object" @ object_ <: E.string; + "state" @? st <: state; + ] + +let tag ({ ty; href; name }: Types.tag) = + ap_obj (match ty with `Mention -> "Mention" | `Hashtag -> "Hashtag") [ + "href" @ href <: E.string; + "name" @ name <: E.string; + ] + +let attachment ({media_type; name; url; type_}: Types.attachment) = + obj [ + "type" @? type_ <: E.string; + "mediaType" @? media_type <: E.string; + "name" @? name <: E.string; + "url" @ url <: E.string; + ] + +let note ({ id; actor; to_; in_reply_to; cc; content; sensitive; source; summary; + attachment=att; + published; tags; raw=_ }: Types.note) = + let att = match att with [] -> None | _ -> Some att in + ap_obj "Note" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "attachment" @? att <: E.list attachment; + "to" @ to_ <: E.list E.string; + "inReplyTo" @? in_reply_to <: E.string; + "cc" @ cc <: E.list E.string; + "content" @ content <: E.string; + "sensitive" @ sensitive <: E.bool; + "source" @? source <: E.string; + "summary" @? summary <: E.string; + "published" @? published <: ptime; + "tags" @ tags <: E.list (or_raw tag); + ] + +let block ({ id; obj; published; actor; raw=_ }: Types.block) = + ap_obj "Block" [ + "id" @ id <: E.string; + "object" @ obj <: E.string; + "actor" @ actor <: E.string; + "published" @? published <: ptime; + ] + +let like ({ id; actor; published; obj; raw=_ }: Types.like) = + ap_obj "Like" [ + "id" @ id <: E.string; + "actor" @ actor <: E.string; + "object" @ obj <: E.string; + "published" @? published <: ptime; + ] + + +let core_obj : Types.core_obj E.encoder = function + | `Follow f -> follow f + | `Block b -> block b + | `Note n -> note n + | `Person p -> person p + | `Like l -> like l + | `Link r -> E.string r + +let event enc : _ Types.event E.encoder = function + | `Announce a -> announce enc a + | `Undo u -> undo enc u + | `Delete d -> delete enc d + | `Create c -> create enc c + | `Accept a -> accept enc a + +let object_ : Types.obj E.encoder = function + | #Types.core_obj as c -> core_obj c + | #Types.core_event as e -> event core_obj e + +module Webfinger = struct + + let ty = function + | `ActivityJson -> E.string Constants.ContentType.activity_json + | `Html -> E.string Constants.ContentType.html + | `ActivityJsonLd -> E.string Constants.ContentType.ld_json_activity_streams + | `Json -> E.string Constants.ContentType.plain_json + + let link = function + | Types.Webfinger.Self (t, href) -> obj [ + "href" @ href <: E.string; + "rel" @ Constants.Webfinger.self_rel <: E.string; + "type" @ t <: ty; + ] + | ProfilePage (t, href) -> + obj [ + "href" @ href <: E.string; + "rel" @ Constants.Webfinger.profile_page <: E.string; + "type" @ t <: ty; + ] + | OStatusSubscribe template -> obj [ + "rel" @ Constants.Webfinger.ostatus_rel <: E.string; + "template" @ template <: E.string; + ] + + let query_result ({subject;aliases;links}: Types.Webfinger.query_result) = + obj [ + "subject" @ subject <: E.string; + "aliases" @ aliases <: E.(list string); + "links" @ links <: E.list link; + ] + +end + +module Nodeinfo = struct + + let software (s: Types.Nodeinfo.software) = + obj [ + "name" @ s.name <: E.string; + "version" @ s.version <: E.string; + ] + + let usage_users ({ total; active_month; active_half_year }: Types.Nodeinfo.usage_users) = + obj [ + "total" @ total <: E.int; + "activeMonth" @ active_month <: E.int; + "activeHalfyear" @ active_half_year <: E.int; + ] + + let usage ({ local_posts; users } : Types.Nodeinfo.usage) = + obj [ + "users" @ users <: usage_users; + "localPosts" @ local_posts <: E.int + ] + + let t ({ software=software'; protocols; inbound_services; outbound_services; usage=usage'; + open_registrations; metadata; raw=_ } : Types.Nodeinfo.t) = + obj [ + "version" @ "2.0" <: E.string; + "software" @ software' <: software; + "protocols" @ protocols <: E.list E.string; + "services" @ obj [ + "inbound" @ inbound_services <: E.list E.string; + "outbound" @ outbound_services <: E.list E.string; + ] <: Fun.id; + "usage" @ usage' <: usage; + "openRegistrations" @ open_registrations <: E.bool; + "metadata" @? metadata <: Fun.id; + ] + +end + + +(* module Build (S: sig + * type user + * + * val owner: user -> Uri.t + * + * end) = struct + * + * end *) diff --git a/lib/activitypub/readme.md b/lib/activitypub/readme.md new file mode 100644 index 0000000..7282026 --- /dev/null +++ b/lib/activitypub/readme.md @@ -0,0 +1,5 @@ +# Activitypub Encoding + +This module defines functions to parse to and from activitypub JSONs from other servers. + +Taken from [Ocamlot](https://github.com/gopiandcode/ocamlot). diff --git a/lib/activitypub/types.ml b/lib/activitypub/types.ml new file mode 100644 index 0000000..e4a56e9 --- /dev/null +++ b/lib/activitypub/types.ml @@ -0,0 +1,245 @@ +type yojson = Yojson.Safe.t +let pp_yojson fmt vl = Yojson.Safe.pretty_print fmt vl +let equal_yojson l r = Yojson.Safe.equal l r + +(** * Collections *) +type 'a ordered_collection_page = { + id: string; + prev: string option; + next: string option; + is_ordered: bool; + items: 'a list; + part_of: string option; + total_items: int option; +} [@@deriving show, eq] + + +type 'a ordered_collection = { + id: string option; + total_items: int; + contents: [ + | `Items of (bool * 'a list) + | `First of 'a ordered_collection_page + ] +} [@@deriving show, eq] + +(** * Events *) +type 'a create = { + id: string; + actor: string; + published: Ptime.t option; + to_: string list; + cc: string list; + direct_message: bool; + obj: 'a; + raw: yojson; +} [@@deriving show, eq] + + +type 'a announce = { + id: string; + actor: string; + published: Ptime.t option; + to_: string list; + cc: string list; + obj: 'a; + raw: yojson; +} [@@deriving show, eq] + + +type 'a accept = { + id: string; + actor: string; + published: Ptime.t option; + obj: 'a; + raw: yojson; +} [@@deriving show, eq] + +type 'a undo = { + id: string; + actor: string; + published: Ptime.t option; + obj: 'a; + raw: yojson; +} [@@deriving show, eq] + +type 'a delete = { + id: string; + actor: string; + published: Ptime.t option; + obj: 'a; + raw: yojson; +} +[@@deriving show, eq] + +type 'a event = [ + `Create of 'a create + | `Announce of 'a announce + | `Accept of 'a accept + | `Undo of 'a undo + | `Delete of 'a delete +] [@@deriving show, eq] + + +(** * Objects *) +type public_key = { + id: string; + owner: string; + pem: string; +} [@@deriving show, eq] + +type person = { + id: string; + name: string option; + url: string option; + + preferred_username: string option; + + inbox: string; + outbox: string; + + summary: string option; + + public_key: public_key; + + manually_approves_followers: bool; + + discoverable: bool; + followers: string option; + following: string option; + icon: string option; + raw: yojson; +} [@@deriving show, eq] + +type follow = { + id: string; + actor: string; + cc: string list; + to_: string list; + object_: string; + state: [`Pending | `Cancelled ] option; + raw: yojson; +} [@@deriving show, eq] + +type tag = { + ty: [`Mention | `Hashtag ]; + href: string; + name: string; +} [@@deriving show, eq] + +type attachment = { + media_type: string option; + name: string option; + type_: string option; + url: string; +} [@@deriving show, eq] + +type note = { + id: string; + actor: string; + attachment: attachment list; + to_: string list; + in_reply_to: string option; + cc: string list; + content: string; + sensitive: bool; + source: string option; + summary: string option; + published: Ptime.t option; + tags: [ `Raw of yojson | `Value of tag ] list; + raw: yojson; +} [@@deriving show, eq] + +type block = { + id: string; + obj: string; + published: Ptime.t option; + actor: string; + raw: yojson; +} [@@deriving show, eq] + +type like = { + id: string; + actor: string; + published: Ptime.t option; + obj: string; + raw: yojson; +} +[@@deriving show, eq] + + +type core_obj = [ + `Person of person + | `Follow of follow + | `Note of note + | `Block of block + | `Like of like + | `Link of string +] [@@deriving show, eq] + +type core_event = core_obj event +[@@deriving show, eq] + +type obj = [ core_obj | core_event ] +[@@deriving show, eq] + +module Webfinger = struct + + type ty = [ `Html | `Json | `ActivityJson | `ActivityJsonLd ] + [@@deriving show, eq] + + type link = + | Self of ty * string + | ProfilePage of ty * string + | OStatusSubscribe of string + [@@deriving show, eq] + + type query_result = { + subject: string; + aliases: string list; + links: link list; + } + [@@deriving show, eq] + + let self_link query = + query.links + |> List.find_map (function + | Self ((`ActivityJson | `ActivityJsonLd | `Json), url) -> Some (Uri.of_string url) + | _ -> None) + +end + +module Nodeinfo = struct + + type software = { + name: string; + version: string; + } + [@@deriving show, eq] + + type usage_users = { + total: int; + active_month: int; + active_half_year: int; + } + [@@deriving show, eq] + + type usage = { + local_posts: int; + users: usage_users; + } + [@@deriving show, eq] + + type t = { + software: software; + protocols: string list; + inbound_services: string list; + outbound_services: string list; + usage: usage; + open_registrations: bool; + metadata: yojson option; + raw: yojson; + } + [@@deriving show, eq] + +end diff --git a/lib/dune b/lib/dune new file mode 100644 index 0000000..f04ae9a --- /dev/null +++ b/lib/dune @@ -0,0 +1,18 @@ +(library + (name ann_bloop) + (libraries uri + cohttp-lwt-unix + containers + base64 + mirage-crypto + x509 + lwt + cohttp + dream + calendar + ptime + decoders-yojson + ) + (preprocess (pps lwt_ppx ppx_yojson_conv ppx_inline_test )) + (inline_tests) + ) diff --git a/lib/http_date.ml b/lib/http_date.ml new file mode 100644 index 0000000..38bda02 --- /dev/null +++ b/lib/http_date.ml @@ -0,0 +1,37 @@ +(* Taken from https://github.com/gopiandcode/ocamlot *) +let parse_date = Parser.parse_date +let parse_date_exn = Parser.parse_date_exn + +let to_utc_string t = + let www = + Ptime.weekday t |> function + | `Sat -> "Sat" + | `Fri -> "Fri" + | `Mon -> "Mon" + | `Wed -> "Wed" + | `Sun -> "Sun" + | `Tue -> "Tue" + | `Thu -> "Thu" + in + let (yyyy, mmm, dd), ((hh, mm, ss), _) = Ptime.to_date_time t in + let mmm = + match mmm with + | 1 -> "Jan" + | 2 -> "Feb" + | 3 -> "Mar" + | 4 -> "Apr" + | 5 -> "May" + | 6 -> "Jun" + | 7 -> "Jul" + | 8 -> "Aug" + | 9 -> "Sep" + | 10 -> "Oct" + | 11 -> "Nov" + | 12 -> "Dec" + | _ -> assert false + in + Printf.sprintf "%s, %02d %s %04d %02d:%02d:%02d GMT" www dd mmm yyyy hh mm ss + +let%test "rev" = + List.equal Int.equal (List.rev [ 3; 2; 1 ]) [ 3; 2; 1 ] + diff --git a/lib/parser.ml b/lib/parser.ml new file mode 100644 index 0000000..2e9d759 --- /dev/null +++ b/lib/parser.ml @@ -0,0 +1,75 @@ +(*---------------------------------------------------------------------------- + Copyright (c) 2015 Inhabited Type LLC. + All rights reserved. + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + 1. Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + 3. Neither the name of the author nor the names of his contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + ----------------------------------------------------------------------------*) + +let parse_date_exn s = + try + Scanf.sscanf s "%3s, %d %s %4d %d:%d:%d %s" + (fun _wday mday mon year hour min sec tz -> + let months = + [ + ("Jan", 1); + ("Feb", 2); + ("Mar", 3); + ("Apr", 4); + ("May", 5); + ("Jun", 6); + ("Jul", 7); + ("Aug", 8); + ("Sep", 9); + ("Oct", 10); + ("Nov", 11); + ("Dec", 12); + ] + in + let parse_tz = function + | "" | "Z" | "GMT" | "UTC" | "UT" -> 0 + | "PST" -> -480 + | "MST" | "PDT" -> -420 + | "CST" | "MDT" -> -360 + | "EST" | "CDT" -> -300 + | "EDT" -> -240 + | s -> + Scanf.sscanf s "%c%02d%_[:]%02d" (fun sign hour min -> + min + (hour * if sign = '-' then -60 else 60)) + in + let mon = List.assoc mon months in + let year = + if year < 50 then year + 2000 + else if year < 1000 then year + 1900 + else year + in + let date = (year, mon, mday) in + let time = ((hour, min, sec), parse_tz tz * 60) in + let ptime = Ptime.of_date_time (date, time) in + match ptime with + | None -> raise (Invalid_argument "Invalid date string") + | Some date -> date) + with + | Scanf.Scan_failure e -> raise (Invalid_argument e) + | Not_found -> raise (Invalid_argument "Invalid date string") + +let parse_date s = try Some (parse_date_exn s) with Invalid_argument _ -> None diff --git a/lib/sig.ml b/lib/sig.ml new file mode 100644 index 0000000..b4f49d7 --- /dev/null +++ b/lib/sig.ml @@ -0,0 +1,167 @@ +(* Taken from https://gopiandcode.uk/logs/log-writing-activitypub.html + License is AGPL-v3 +*) +open Containers +module StringMap = Map.Make (String) + +let drop_quotes str = String.sub str 1 (String.length str - 2) + +let body_digest body = + Mirage_crypto.Hash.SHA256.digest (Cstruct.of_string body) |> Cstruct.to_string + |> fun hash -> "SHA-256=" ^ Base64.encode_string hash + +let req_headers headers = Cohttp.Header.to_list headers |> StringMap.of_list + +let split_equals str = + match String.index_opt str '=' with + | Some ind -> + let key = String.sub str 0 ind in + let data = String.sub str (ind + 1) (String.length str - ind - 1) in + Some (key, data) + | _ -> None + +(* constructs a signed string *) +let build_signed_string ~signed_headers ~meth ~path ~headers ~body_digest = + (* (request-target) user-agent host date digest content-type *) + String.split_on_char ' ' signed_headers + |> List.map (function + | "(request-target)" -> + "(request-target): " ^ String.lowercase_ascii meth ^ " " ^ path + | "digest" -> "digest: " ^ body_digest + | header -> + header ^ ": " + ^ (StringMap.find_opt header headers |> Option.value ~default:"")) + |> String.concat "\n" + +let parse_signature signature = + String.split_on_char ',' signature + |> List.filter_map split_equals + |> List.map (Pair.map_snd drop_quotes) + |> StringMap.of_list + +let verify ~signed_string ~signature pubkey = + let result = + X509.Public_key.verify `SHA256 ~scheme:`RSA_PKCS1 + ~signature:(Cstruct.of_string signature) + pubkey + (`Message (Cstruct.of_string signed_string)) + in + match result with + | Ok () -> true + | Error (`Msg e) -> + Dream.log + "error while verifying: %s\n\nsigned_string is:%s\n\nsignature is:%s\n" + e signed_string signature; + false + +let encrypt (privkey : X509.Private_key.t) str = + Base64.encode + (X509.Private_key.sign `SHA256 ~scheme:`RSA_PKCS1 privkey + (`Message (Cstruct.of_string str)) + |> Result.get_exn |> Cstruct.to_string) + +let time_now () = + CalendarLib.Calendar.now () + |> CalendarLib.Calendar.to_unixfloat |> Ptime.of_float_s + |> Option.get_exn_or "invalid date" + +let verify_request taken_public_key (req : Dream.request) = + let ( let+ ) x f = + match x with None -> Lwt.return (Ok false) | Some v -> f v + in + let ( let@ ) x f = Lwt.bind x f in + let meth = + Dream.method_ req |> Dream.method_to_string |> String.lowercase_ascii + in + let path = Dream.target req in + let headers = + Dream.all_headers req + |> List.map (Pair.map_fst String.lowercase_ascii) + |> StringMap.of_list + in + let+ signature = Dream.header req "Signature" in + let signed_headers = parse_signature signature in + (* 1. build signed string *) + let@ body = Dream.body req in + let body_digest = body_digest body in + let+ public_key = taken_public_key in + (* signed headers *) + let+ headers_in_signed_string = StringMap.find_opt "headers" signed_headers in + (* signed string *) + let signed_string = + build_signed_string ~signed_headers:headers_in_signed_string ~meth ~path + ~headers ~body_digest + in + (* 2. retrieve signature *) + let+ signature = StringMap.find_opt "signature" signed_headers in + let+ signature = Base64.decode signature |> Result.to_opt in + (* verify signature against signed string with public key *) + Lwt_result.return @@ verify ~signed_string ~signature public_key + +let build_signed_headers ~priv_key ~key_id ~headers ?body_str ~current_time + ~method_ ~uri () = + let signed_headers = + match body_str with + | Some _ -> "(request-target) content-length host date digest" + | None -> "(request-target) host date" + in + + let body_str_len = Option.map Fun.(Int.to_string % String.length) body_str in + let body_digest = Option.map body_digest body_str in + + let date = Http_date.to_utc_string current_time in + let host = uri |> Uri.host |> Option.get_exn_or "no host for request" in + + let signature_string = + let opt name vl = + match vl with None -> Fun.id | Some vl -> StringMap.add name vl + in + let to_be_signed = + build_signed_string ~signed_headers + ~meth:(method_ |> String.lowercase_ascii) + ~path:(Uri.path uri) + ~headers: + (opt "content-length" body_str_len + @@ StringMap.add "date" date @@ StringMap.add "host" host @@ headers) + ~body_digest:(Option.value body_digest ~default:"") + in + + let signed_string = encrypt priv_key to_be_signed |> Result.get_exn in + Printf.sprintf + {|keyId="%s",algorithm="rsa-sha256",headers="%s",signature="%s"|} key_id + signed_headers signed_string + in + List.fold_left + (fun map (k, v) -> + match v with None -> map | Some v -> StringMap.add k v map) + headers + [ + ("Digest", body_digest); + ("Date", Some date); + ("Host", Some host); + ("Signature", Some signature_string); + ("Content-Length", body_str_len); + ] + |> StringMap.to_list + +let sign_headers ~priv_key ~key_id ?(body : Cohttp_lwt.Body.t option) + ~(headers : Cohttp.Header.t) ~uri ~method_ () = + let ( let* ) x f = Lwt.bind x f in + + let* body_str = + match body with + | None -> Lwt.return None + | Some body -> Lwt.map Option.some (Cohttp_lwt.Body.to_string body) + in + let current_time = time_now () in + + let headers = + List.fold_left + (fun header (key, vl) -> Cohttp.Header.add header key vl) + headers + (build_signed_headers ~priv_key ~key_id ~headers:(req_headers headers) + ?body_str ~current_time + ~method_:(Cohttp.Code.string_of_method method_) + ~uri ()) + in + Lwt.return headers diff --git a/lib/user.ml b/lib/user.ml new file mode 100644 index 0000000..ba802c0 --- /dev/null +++ b/lib/user.ml @@ -0,0 +1,31 @@ +open Ppx_yojson_conv_lib.Yojson_conv.Primitives +open Cohttp +open Cohttp_lwt_unix +open Lwt + +type public_key = { + id : string; + owner : string; + public_key_pem : string; [@key "publicKeyPem"] +} +[@@deriving yojson] [@@yojson.allow_extra_fields] + +type t = { name : string; public_key : public_key [@key "publicKey"] } +[@@deriving yojson] [@@yojson.allow_extra_fields] + +let activity_header = + Some (Header.of_list [ ("Accept", "application/activity+json") ]) + +let get_user actor_url = + let%lwt _, body = + Client.get ?headers:activity_header (Uri.of_string actor_url) + in + body |> Cohttp_lwt.Body.to_string >|= fun body -> + let body = Yojson.Safe.from_string body |> t_of_yojson in + body + +let get_public_pem user = + user.public_key.public_key_pem |> Cstruct.of_string + |> X509.Public_key.decode_pem + +let name user = user.name diff --git a/package-defs.json b/package-defs.json new file mode 100644 index 0000000..026f3db --- /dev/null +++ b/package-defs.json @@ -0,0 +1 @@ +{"__opam_nix_env":{},"__opam_nix_regen":null,"angstrom":{"authors":["Spiros Eliopoulos <spiros@inhabitedtype.com>"],"bug-reports":"https://github.com/inhabitedtype/angstrom/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.04.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.8","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.1","prefix_relop":"geq"}}],"val":"alcotest"},"bigstringaf",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.14.0","prefix_relop":"geq"}}],"val":"ppx_let"},{"conditions":[{"id":"build"}],"val":"ocaml-syntax-shims"}],"description":"\nAngstrom is a parser-combinator library that makes it easy to write efficient,\nexpressive, and reusable parsers suitable for high-performance applications. It\nexposes monadic and applicative interfaces for composition, and supports\nincremental input through buffered and unbuffered interfaces. Both interfaces\ngive the user total control over the blocking behavior of their application,\nwith the unbuffered interface enabling zero-copy IO. Parsers are backtracking by\ndefault and support unbounded lookahead.","dev-repo":"git+https://github.com/inhabitedtype/angstrom.git","files-contents":{},"homepage":"https://github.com/inhabitedtype/angstrom","isLocal":false,"license":"BSD-3-clause","maintainer":"Spiros Eliopoulos <spiros@inhabitedtype.com>","name":"angstrom","opam-version":"2.0","synopsis":"Parser combinators built for speed and memory-efficiency","url":{"section":{"checksum":"md5=58ebc718a920c31ec3eb38f4aa1bea51","src":"https://github.com/inhabitedtype/angstrom/archive/0.16.0.tar.gz"}},"version":"0.16.0"},"ann_bloop":{"authors":["Marc Coquand"],"bug-reports":"https://github.com/username/reponame/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":["ocaml",{"conditions":[{"arg":"3.11","prefix_relop":"geq"}],"val":"dune"},"dream","ppx_yojson_conv","crunch","cohttp","lwt_ppx","cohttp-lwt-unix","containers","calendar","ptime","mirage-crypto-rng","mirage-crypto-rng-lwt","ppx_inline_test","ppx_deriving","decoders-yojson",{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"A longer description","dev-repo":"git+https://github.com/username/reponame.git","doc":"https://url/to/documentation","files-contents":{},"homepage":"https://github.com/username/reponame","isLocal":true,"license":"AGPL-3.0-only","maintainer":["Marc Coquand"],"name":"ann_bloop","opam-version":"2.0","synopsis":"A short synopsis","tags":["topics","to describe","your","project"],"version":"dev"},"asn1-combinators":{"authors":"David Kaloper Meršinjak","bug-reports":"https://github.com/mirleft/ocaml-asn1-combinators/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},"zarith","ptime",{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"\nasn1-combinators is a library for expressing ASN.1 in OCaml. Skip the notation\npart of ASN.1, and embed the abstract syntax directly in the language. These\nabstract syntax representations can be used for parsing, serialization, or\nrandom testing.\n\nThe only ASN.1 encodings currently supported are BER and DER.\n","dev-repo":"git+https://github.com/mirleft/ocaml-asn1-combinators.git","doc":"https://mirleft.github.io/ocaml-asn1-combinators/doc","files-contents":{},"homepage":"https://github.com/mirleft/ocaml-asn1-combinators","isLocal":false,"license":"ISC","maintainer":"David Kaloper Meršinjak <dk505@cam.ac.uk>","name":"asn1-combinators","opam-version":"2.0","synopsis":"Embed typed ASN.1 grammars in OCaml","url":{"section":{"checksum":["sha256=012ade0d8869ef621063752c1cf8ea026f6bc702fed10df9af56688e291b1a91","sha512=4c1b28f1d230395ff1ad3b8e8d03981b10015062ec270f29e2521914eb64c2fa4d5df68363e339e9a1158c3b58aef0e25156f7ec6addd85a580fecadc17edfac"],"src":"https://github.com/mirleft/ocaml-asn1-combinators/releases/download/v0.2.6/asn1-combinators-v0.2.6.tbz"}},"version":"0.2.6","x-commit-hash":"1fc666e8b4231846cf65704ffcb09d240981dcb6"},"astring":{"authors":["The astring programmers"],"bug-reports":"https://github.com/dbuenzli/astring/issues","build":[["ocaml","pkg/pkg.ml","build","--pinned","%{pinned}%"]],"depends":[{"conditions":[{"arg":"4.05.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"id":"build"}],"val":"topkg"}],"description":"\nAstring exposes an alternative `String` module for OCaml. This module\ntries to balance minimality and expressiveness for basic, index-free,\nstring processing and provides types and functions for substrings,\nstring sets and string maps.\n\nRemaining compatible with the OCaml `String` module is a non-goal. The\n`String` module exposed by Astring has exception safe functions,\nremoves deprecated and rarely used functions, alters some signatures\nand names, adds a few missing functions and fully exploits OCaml's\nnewfound string immutability.\n\nAstring depends only on the OCaml standard library. It is distributed\nunder the ISC license.\n","dev-repo":"git+http://erratique.ch/repos/astring.git","doc":"https://erratique.ch/software/astring/doc","files-contents":{},"homepage":"https://erratique.ch/software/astring","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"astring","opam-version":"2.0","synopsis":"Alternative String module for OCaml","tags":["string","org:erratique"],"url":{"section":{"archive":"https://erratique.ch/software/astring/releases/astring-0.8.5.tbz","checksum":"e148907c24157d1df43bec89b58b3ec8"}},"version":"0.8.5"},"base":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/base/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"sexplib0"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},"dune-configurator"],"description":"\nFull standard library replacement for OCaml\n\nBase is a complete and portable alternative to the OCaml standard\nlibrary. It provides all standard functionalities one would expect\nfrom a language standard library. It uses consistent conventions\nacross all of its module.\n\nBase aims to be usable in any context. As a result system dependent\nfeatures such as I/O are not offered by Base. They are instead\nprovided by companion libraries such as stdio:\n\n https://github.com/janestreet/stdio\n","dev-repo":"git+https://github.com/janestreet/base.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/base/index.html","files-contents":{},"homepage":"https://github.com/janestreet/base","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"base","opam-version":"2.0","synopsis":"Full standard library replacement for OCaml","url":{"section":{"checksum":["md5=04572fc23a4651604cfcab83f720cb4c","sha512=69380ed392faf4495459f97f70a10a6959fce71d2e6ba093472fc272141646307fd7872407de855dfa48ef0435f6587eae5aa50f4a67eac40a9e1946d0c3c070"],"src":"https://github.com/janestreet/base/archive/refs/tags/v0.16.3.tar.gz"}},"version":"v0.16.3"},"base-bigarray":{"description":"\nBigarray library distributed with the OCaml compiler\n","files-contents":{},"isLocal":false,"maintainer":"https://github.com/ocaml/opam-repository/issues","name":"base-bigarray","opam-version":"2.0","version":"base"},"base-bytes":{"authors":" ","depends":[{"conditions":[{"arg":"4.02.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.5.3","prefix_relop":"geq"}],"val":"ocamlfind"}],"files-contents":{},"homepage":" ","isLocal":false,"maintainer":" ","name":"base-bytes","opam-version":"2.0","synopsis":"Bytes library distributed with the OCaml compiler","version":"base"},"base-domains":{"depends":[{"lhs":{"conditions":[{"arg":"5.0","prefix_relop":"geq"}],"val":"ocaml"},"logop":"or","rhs":{"conditions":[{"lhs":{"lhs":{"lhs":{"lhs":{"lhs":{"arg":"4.14.0+domains","prefix_relop":"eq"},"logop":"or","rhs":{"arg":"4.12.0+domains+effects","prefix_relop":"eq"}},"logop":"or","rhs":{"arg":"4.12.0+domains","prefix_relop":"eq"}},"logop":"or","rhs":{"arg":"4.10.0+multicore","prefix_relop":"eq"}},"logop":"or","rhs":{"arg":"4.10.0+multicore+no-effect-syntax","prefix_relop":"eq"}},"logop":"or","rhs":{"arg":"4.06.1+multicore","prefix_relop":"eq"}}],"val":"ocaml-variants"}}],"description":"\nDomains-based parallelism distributed with the Multicore OCaml compiler\"\n","files-contents":{},"isLocal":false,"maintainer":"https://github.com/ocaml-multicore/multicore-opam/issues","name":"base-domains","opam-version":"2.0","version":"base"},"base-nnp":{"depends":{"lhs":{"lhs":"base-domains","logop":"or","rhs":"ocaml-option-nnp"},"logop":"or","rhs":{"conditions":[{"arg":"4.06.1+no-naked-pointers+flambda","prefix_relop":"eq"}],"val":"ocaml-variants"}},"description":"\nInstalled when the compiler does not permit naked pointers in\nthe heap. Prior to OCaml 5.00.0, this mode was expressly selected\nby configuring with --disable-naked-pointers. The shared memory\nparallelism added in OCaml 5.00.0 requires this mode.\n","files-contents":{},"isLocal":false,"maintainer":"https://github.com/ocaml/opam-repository/issues","name":"base-nnp","opam-version":"2.0","synopsis":"Naked pointers prohibited in the OCaml heap","version":"base"},"base-threads":{"description":"\nThreads library distributed with the OCaml compiler\n","files-contents":{},"isLocal":false,"maintainer":"https://github.com/ocaml/opam-repository/issues","name":"base-threads","opam-version":"2.0","version":"base"},"base-unix":{"description":"\nUnix library distributed with the OCaml compiler\n","files-contents":{},"isLocal":false,"maintainer":"https://github.com/ocaml/opam-repository/issues","name":"base-unix","opam-version":"2.0","version":"base"},"base64":{"authors":["Thomas Gazagnaire","Anil Madhavapeddy","Calascibetta Romain","Peter Zotov"],"bug-reports":"https://github.com/mirage/ocaml-base64/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.3","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.7","prefix_relop":"geq"}}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"bos"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"\nBase64 is a group of similar binary-to-text encoding schemes that represent\nbinary data in an ASCII string format by translating it into a radix-64\nrepresentation. It is specified in RFC 4648.\n","dev-repo":"git+https://github.com/mirage/ocaml-base64.git","doc":"https://mirage.github.io/ocaml-base64/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-base64","isLocal":false,"license":"ISC","maintainer":"mirageos-devel@lists.xenproject.org","name":"base64","opam-version":"2.0","synopsis":"Base64 encoding for OCaml","url":{"section":{"checksum":["sha256=d8fedaa59bd12feae7acc08b5928dd478aac523f4ca8d240470d2500651c65ed","sha512=278bd2029800d90ed88ff59b9de723013e645523556a1667b64178d6b5058a7d6da91efffef3589c35569b5fa10ddee74c93f5a3d156b9146c8af5b7fe44aeaf"],"src":"https://github.com/mirage/ocaml-base64/releases/download/v3.5.1/base64-3.5.1.tbz"}},"version":"3.5.1","x-commit-hash":"084346f14ed1e6706d733402dd6ff65b0dc4f718"},"bigarray-compat":{"authors":["Lucas Pluvinage <lucas.pluvinage@gmail.com>"],"bug-reports":"https://github.com/mirage/bigarray-compat/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"}],"dev-repo":"git+https://github.com/mirage/bigarray-compat.git","files-contents":{},"homepage":"https://github.com/mirage/bigarray-compat","isLocal":false,"license":"ISC","maintainer":"Lucas Pluvinage <lucas.pluvinage@gmail.com>","name":"bigarray-compat","opam-version":"2.0","synopsis":"Compatibility library to use Stdlib.Bigarray when possible","url":{"section":{"checksum":["sha256=434469a48d5c84e80d621b13d95eb067f8138c1650a1fd5ae6009a19b93718d5","sha512=7be283fd957ee168ce1e62835d22114da405e4b7da9619b4f2030a832d45ca210a0c8f1d1c57c92e224f3512308a8a0f0923b94f44b6f582acbe0e7728d179d4"],"src":"https://github.com/mirage/bigarray-compat/releases/download/v1.1.0/bigarray-compat-1.1.0.tbz"}},"version":"1.1.0","x-commit-hash":"2ea842ba4ab2cfee7b711f7ad927917f3179a6f9"},"bigarray-overlap":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/dinosaure/overlap/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"3.1.0","prefix_relop":"lt"}],"val":"mirage-xen-posix"},{"conditions":[{"arg":"0.4.3","prefix_relop":"lt"}],"val":"ocaml-freestanding"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.6","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"astring"},{"conditions":[{"id":"with-test"}],"val":"fpath"},{"conditions":[{"id":"with-test"}],"val":"bos"},{"conditions":[{"id":"with-test"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"conf-pkg-config"}],"depopts":["ocaml-freestanding","mirage-xen-posix","js_of_ocaml-compiler"],"description":"A minimal library to know that 2 bigarray share physically the same memory or not.","dev-repo":"git+https://github.com/dinosaure/overlap.git","doc":"https://dinosaure.github.io/overlap/","files-contents":{},"homepage":"https://github.com/dinosaure/overlap","install":[{"conditions":[{"id":"with-test"}],"val":["dune","install","-p",{"id":"name"}]},{"conditions":[{"id":"with-test"}],"val":["./test/test_runes.ml"]}],"isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"bigarray-overlap","opam-version":"2.0","synopsis":"Bigarray.overlap","url":{"section":{"checksum":["sha256=2f520ac470054e335883eba9254bf28b6676ddb57753cfb58b22cf84ae1a66e0","sha512=223f15f815cd944cf2e9955ed9e3cf5608a9db36103e9bb017c2fe452dfb319908228b419f416f6239b8562208027068b7c44e8fb4be6c6a7858ecba540d5439"],"src":"https://github.com/dinosaure/overlap/releases/download/v0.2.1/bigarray-overlap-0.2.1.tbz"}},"version":"0.2.1","x-commit-hash":"ebdd14f8c399ffab0a111bb5a62a0f9aff72bf85"},"bigstringaf":{"authors":["Spiros Eliopoulos <spiros@inhabitedtype.com>"],"bug-reports":"https://github.com/inhabitedtype/bigstringaf/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"conflicts":[{"conditions":[{"arg":"6.0.0","prefix_relop":"lt"}],"val":"mirage-xen"},"ocaml-freestanding",{"conditions":[{"arg":"3.5.0","prefix_relop":"lt"}],"val":"js_of_ocaml"}],"depends":[{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune-configurator"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"}],"description":"\nBigstring intrinsics and fast blits based on memcpy/memmove\n\nThe OCaml compiler has a bunch of intrinsics for Bigstrings, but they're not\nwidely-known, sometimes misused, and so programs that use Bigstrings are slower\nthan they have to be. And even if a library got that part right and exposed the\nintrinsics properly, the compiler doesn't have any fast blits between\nBigstrings and other string-like types.\n\nSo here they are. Go crazy.\n","dev-repo":"git+https://github.com/inhabitedtype/bigstringaf.git","files-contents":{},"homepage":"https://github.com/inhabitedtype/bigstringaf","isLocal":false,"license":"BSD-3-clause","maintainer":"Spiros Eliopoulos <spiros@inhabitedtype.com>","name":"bigstringaf","opam-version":"2.0","synopsis":"Bigstring intrinsics and fast blits based on memcpy/memmove","url":{"section":{"checksum":"md5=909fdc277cf03096a35b565325d5314a","src":"https://github.com/inhabitedtype/bigstringaf/archive/0.9.1.tar.gz"}},"version":"0.9.1"},"bisect_ppx":{"authors":["Xavier Clerc <bisect@x9c.fr>","Leonid Rozenberg <leonidr@gmail.com>","Anton Bachin <antonbachin@yahoo.com>"],"bug-reports":"https://github.com/aantron/bisect_ppx/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@compatible"]}],"depends":["base-unix",{"conditions":[{"arg":"1.0.0","prefix_relop":"geq"}],"val":"cmdliner"},{"conditions":[{"arg":"2.7.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"3.0.0","prefix_relop":"geq"}}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.16.0","prefix_relop":"eq"}}],"val":"ocamlformat"}],"description":"Bisect_ppx helps you test thoroughly. It is a small preprocessor\nthat inserts instrumentation at places in your code, such as if-then-else and\nmatch expressions. After you run tests, Bisect_ppx gives a nice HTML report\nshowing which places were visited and which were missed.\n\nUsage is simple - add package bisect_ppx when building tests, run your tests,\nthen run the Bisect_ppx report tool on the generated visitation files.","dev-repo":"git+https://github.com/aantron/bisect_ppx.git","doc":"https://github.com/aantron/bisect_ppx","files-contents":{},"homepage":"https://github.com/aantron/bisect_ppx","isLocal":false,"license":"MIT","maintainer":["Anton Bachin <antonbachin@yahoo.com>","Leonid Rozenberg <leonidr@gmail.com>"],"name":"bisect_ppx","opam-version":"2.0","synopsis":"Code coverage for OCaml","url":{"section":{"checksum":"md5=8c755c13e8d90f665986d842a41669f5","src":"https://github.com/aantron/bisect_ppx/archive/2.8.3.tar.gz"}},"version":"2.8.3"},"bos":{"authors":["The bos programmers"],"bug-reports":"https://github.com/dbuenzli/bos/issues","build":[["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%"]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"},"base-unix",{"conditions":[{"arg":"0.7.0","prefix_relop":"geq"}],"val":"rresult"},"astring",{"conditions":[{"arg":"0.7.3","prefix_relop":"geq"}],"val":"fpath"},{"conditions":[{"arg":"0.8.10","prefix_relop":"geq"}],"val":"fmt"},"logs",{"conditions":[{"id":"with-test"}],"val":"mtime"}],"description":"\nBos provides support for basic and robust interaction with the\noperating system in OCaml. It has functions to access the process\nenvironment, parse command line arguments, interact with the file\nsystem and run command line programs.\n\nBos works equally well on POSIX and Windows operating systems.\n\nBos depends on [Rresult][rresult], [Astring][astring], [Fmt][fmt],\n[Fpath][fpath] and [Logs][logs] and the OCaml Unix library. It is\ndistributed under the ISC license.\n\n[rresult]: http://erratique.ch/software/rresult\n[astring]: http://erratique.ch/software/astring\n[fmt]: http://erratique.ch/software/fmt\n[fpath]: http://erratique.ch/software/fpath\n[logs]: http://erratique.ch/software/logs\n\nHome page: http://erratique.ch/software/bos \nContact: Daniel Bünzli `<daniel.buenzl i@erratique.ch>`","dev-repo":"git+https://erratique.ch/repos/bos.git","doc":"https://erratique.ch/software/bos/doc","files-contents":{},"homepage":"https://erratique.ch/software/bos","isLocal":false,"license":["ISC"],"maintainer":["Daniel Bünzli <daniel.buenzl i@erratique.ch>"],"name":"bos","opam-version":"2.0","synopsis":"Basic OS interaction for OCaml","tags":["os","system","cli","command","file","path","log","unix","org:erratique"],"url":{"section":{"checksum":"sha512=8daeb8a4c2dd1f2460f6274ada19f4f1b6ebe875ff83a938c93418ce0e6bdb74b8afc5c9a7d410c1c9df2dad030e4fa276b6ed2da580639484e8b5bc92610b1d","src":"https://erratique.ch/software/bos/releases/bos-0.2.1.tbz"}},"version":"0.2.1"},"ca-certs":{"authors":["Etienne Millon <me@emillon.org>, Hannes Mehnert <hannes@mehnert.org>"],"bug-reports":"https://github.com/mirage/ca-certs/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"}}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"conflicts":[{"conditions":[{"arg":"1.5","prefix_relop":"lt"}],"val":"result"}],"depends":[{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"astring","bos","fpath","ptime","logs","mirage-crypto",{"conditions":[{"arg":"0.13.0","prefix_relop":"geq"}],"val":"x509"},{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.7","prefix_relop":"geq"}}],"val":"fmt"}],"depexts":[{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"freebsd"}],"val":["ca_root_nss"]}],"description":"\nTLS requires a set of root anchors (Certificate Authorities) to\nauthenticate servers. This library exposes this list so that it can be\nregistered with ocaml-tls.\n","dev-repo":"git+https://github.com/mirage/ca-certs.git","doc":"https://mirage.github.io/ca-certs/doc","files-contents":{},"homepage":"https://github.com/mirage/ca-certs","isLocal":false,"license":"ISC","maintainer":["Etienne Millon <me@emillon.org>"],"name":"ca-certs","opam-version":"2.0","synopsis":"Detect root CA certificates from the operating system","tags":["org:mirage"],"url":{"section":{"checksum":["sha256=d2d8d6457d915ef6d783def82f3be5ec2f56f92e20214f58edd63c9c2fc60e9c","sha512=e945112be3b2f1fbcaeb95aebb600cd5119f1f05583ebcc0a4a20dd159d8cfec5adc3443aae678ee159c0e0c32b1d7c0ba3ba4405e3483e3f565e4d29d3da0f7"],"src":"https://github.com/mirage/ca-certs/releases/download/v0.2.3/ca-certs-0.2.3.tbz"}},"version":"0.2.3","x-commit-hash":"9ee07b8ab77eb9ec8b6d84f98359e45e1beb9b9d"},"calendar":{"authors":"Julien Signoles","bug-reports":"https://github.com/ocaml-community/calendar/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-doc"}],"val":["dune","build","@doc","-p",{"id":"name"},"-j",{"id":"jobs"}]},{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.7.2","prefix_relop":"geq"}],"val":"re"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-doc"}],"val":"odoc"},{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"Calendar is a library for handling dates and times in your program.","dev-repo":"git+https://github.com/ocaml-community/calendar","doc":"https://ocaml-community.github.io/calendar/","files-contents":{},"homepage":"https://github.com/ocaml-community/calendar","isLocal":false,"license":"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception","maintainer":"ocaml-community","name":"calendar","opam-version":"2.0","synopsis":"Library for handling dates and times in your program","tags":["calendar","date","time","datetime"],"url":{"section":{"checksum":["md5=8c7207407fc6b4d0bd3d05ed3c13f91a","sha512=cf8a5cfbfb8879da7bcacf765d5461523cbc4f0c13133dfb2f311b051ed95b5f72815af5ca2836294a793d9b57bfc4cc1abbb8b54e17954cb4ecc99e1743bdc3"],"src":"https://github.com/ocaml-community/calendar/archive/refs/tags/v3.0.0.tar.gz"}},"version":"3.0.0"},"camlp-streams":{"authors":["Daniel de Rauglaudre","Xavier Leroy"],"bug-reports":"https://github.com/ocaml/camlp-streams/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\n\nThis package provides two library modules:\n- Stream: imperative streams, with in-place update and memoization\n of the latest element produced.\n- Genlex: a small parameterized lexical analyzer producing streams\n of tokens from streams of characters.\n\nThe two modules are designed for use with Camlp4 and Camlp5:\n- The stream patterns and stream expressions of Camlp4/Camlp5 consume\n and produce data of type 'a Stream.t.\n- The Genlex tokenizer can be used as a simple lexical analyzer for\n Camlp4/Camlp5-generated parsers.\n\nThe Stream module can also be used by hand-written recursive-descent\nparsers, but is not very convenient for this purpose.\n\nThe Stream and Genlex modules have been part of the OCaml standard library\nfor a long time, and have been distributed as part of the core OCaml system.\nThey will be removed from the OCaml standard library at some future point,\nbut will be maintained and distributed separately in this camlpstreams package.\n","dev-repo":"git+https://github.com/ocaml/camlp-streams.git","files-contents":{},"homepage":"https://github.com/ocaml/camlp-streams","isLocal":false,"license":"LGPL-2.1-only WITH OCaml-LGPL-linking-exception","maintainer":["Florian Angeletti <florian.angeletti@inria.fr>","Xavier Leroy <xavier.leroy@college-de-france.fr>"],"name":"camlp-streams","opam-version":"2.0","synopsis":"The Stream and Genlex libraries for use with Camlp4 and Camlp5","url":{"section":{"checksum":["md5=afc874b25f7a1f13e8f5cfc1182b51a7","sha512=2efa8dd4a636217c8d49bac1e4e7e5558fc2f45cfea66514140a59fd99dd08d61fb9f1e17804997ff648b71b13820a5d4a1eb70fed9d848aa2abd6e41f853c86"],"src":"https://github.com/ocaml/camlp-streams/archive/v5.0.1.tar.gz"}},"version":"5.0.1"},"caqti":{"authors":["Petter A. Urkedal <paurkedal@gmail.com>","Nathan Rebours <nathan@cryptosense.com>"],"bug-reports":"https://github.com/paurkedal/ocaml-caqti/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]},{"conditions":[{"id":"with-doc"}],"val":["dune","build","@doc","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.5.0","prefix_relop":"geq"}}],"val":"alcotest"},{"conditions":[{"arg":"0.14.0","prefix_relop":"geq"}],"val":"angstrom"},"bigstringaf",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.1.0","prefix_relop":"geq"}}],"val":"cmdliner"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.1.0","prefix_relop":"geq"}}],"val":"cppo"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"logs",{"conditions":[{"arg":"4.04.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-doc"}],"val":"odoc"},"ptime",{"conditions":[{"id":"with-test"}],"val":"re"},{"conditions":[{"arg":"1.9.0","prefix_relop":"geq"}],"val":"uri"}],"description":"\nCaqti provides a monadic cooperative-threaded OCaml connector API for\nrelational databases.\n\nThe purpose of Caqti is further to help make applications independent of a\nparticular database system. This is achieved by defining a common signature,\nwhich is implemented by the database drivers. Connection parameters are\nspecified as an URI, which is typically provided at run-time. Caqti then\nloads a driver which can handle the URI, and provides a first-class module\nwhich implements the driver API and additional convenience functionality.\n\nCaqti does not make assumptions about the structure of the query language,\nand only provides the type information needed at the edges of communication\nbetween the OCaml code and the database; i.e. for encoding parameters and\ndecoding returned tuples. It is hoped that this agnostic choice makes it a\nsuitable target for higher level interfaces and code generators.","dev-repo":"git+https://github.com/paurkedal/ocaml-caqti.git","doc":"https://paurkedal.github.io/ocaml-caqti/index.html","files-contents":{},"homepage":"https://github.com/paurkedal/ocaml-caqti/","isLocal":false,"license":"LGPL-3.0-or-later WITH LGPL-3.0-linking-exception","maintainer":"Petter A. Urkedal <paurkedal@gmail.com>","name":"caqti","opam-version":"2.0","synopsis":"Unified interface to relational database libraries","url":{"section":{"checksum":["sha256=e1f580848faf3a54f23174067f2c75f77f6a2fe50ca8bc923428d0e1841192c5","sha512=7a11edfcfbbe4855347b066e222cf6bf46d1afedcd4978661b9a2b3931921faa1768a6bc24031fd3afa84537fe2adc8b139399deb77120461bee8fb394d68e82"],"src":"https://github.com/paurkedal/ocaml-caqti/releases/download/v1.9.0/caqti-v1.9.0.tbz"}},"version":"1.9.0","x-commit-hash":"55ab7a2851694f08c62cbb6438c681ebb565636d"},"caqti-lwt":{"authors":"Petter A. Urkedal <paurkedal@gmail.com>","bug-reports":"https://github.com/paurkedal/ocaml-caqti/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]},{"conditions":[{"id":"with-doc"}],"val":["dune","build","@doc","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.5.0","prefix_relop":"geq"}}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.5.0","prefix_relop":"geq"}}],"val":"alcotest-lwt"},{"conditions":[{"lhs":{"arg":"1.9.0","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"1.10.0~","prefix_relop":"lt"}}],"val":"caqti"},{"conditions":[{"lhs":{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.0.0","prefix_relop":"geq"}},"logop":"and","rhs":{"arg":"2.0.0~","prefix_relop":"lt"}}],"val":"caqti-dynload"},{"conditions":[{"lhs":{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.0.0","prefix_relop":"geq"}},"logop":"and","rhs":{"arg":"2.0.0~","prefix_relop":"lt"}}],"val":"caqti-driver-sqlite3"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.1.0","prefix_relop":"geq"}}],"val":"cmdliner"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"logs",{"conditions":[{"arg":"3.2.0","prefix_relop":"geq"}],"val":"lwt"},"ocaml",{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"dev-repo":"git+https://github.com/paurkedal/ocaml-caqti.git","doc":"https://paurkedal.github.io/ocaml-caqti/index.html","files-contents":{},"homepage":"https://github.com/paurkedal/ocaml-caqti/","isLocal":false,"license":"LGPL-3.0-or-later WITH LGPL-3.0-linking-exception","maintainer":"Petter A. Urkedal <paurkedal@gmail.com>","name":"caqti-lwt","opam-version":"2.0","synopsis":"Lwt support for Caqti","url":{"section":{"checksum":["sha256=e1f580848faf3a54f23174067f2c75f77f6a2fe50ca8bc923428d0e1841192c5","sha512=7a11edfcfbbe4855347b066e222cf6bf46d1afedcd4978661b9a2b3931921faa1768a6bc24031fd3afa84537fe2adc8b139399deb77120461bee8fb394d68e82"],"src":"https://github.com/paurkedal/ocaml-caqti/releases/download/v1.9.0/caqti-v1.9.0.tbz"}},"version":"1.9.0","x-commit-hash":"55ab7a2851694f08c62cbb6438c681ebb565636d"},"cmdliner":{"authors":"The cmdliner programmers","bug-reports":"https://github.com/dbuenzli/cmdliner/issues","build":[{"id":"make"},"all","PREFIX=%{prefix}%"],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"}],"description":"Cmdliner allows the declarative definition of command line interfaces\nfor OCaml.\n\nIt provides a simple and compositional mechanism to convert command\nline arguments to OCaml values and pass them to your functions. The\nmodule automatically handles syntax errors, help messages and UNIX man\npage generation. It supports programs with single or multiple commands\nand respects most of the [POSIX][1] and [GNU][2] conventions.\n\nCmdliner has no dependencies and is distributed under the ISC license.\n\n[1]: http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap12.html\n[2]: http://www.gnu.org/software/libc/manual/html_node/Argument-Syntax.html\n\nHome page: http://erratique.ch/software/cmdliner","dev-repo":"git+https://erratique.ch/repos/cmdliner.git","doc":"https://erratique.ch/software/cmdliner/doc","files-contents":{},"homepage":"https://erratique.ch/software/cmdliner","install":[[{"id":"make"},"install","LIBDIR=%{_:lib}%","DOCDIR=%{_:doc}%"],[{"id":"make"},"install-doc","LIBDIR=%{_:lib}%","DOCDIR=%{_:doc}%"]],"isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"cmdliner","opam-version":"2.0","synopsis":"Declarative definition of command line interfaces for OCaml","tags":["cli","system","declarative","org:erratique"],"url":{"section":{"checksum":"sha512=6fcd6a59a6fbc6986b1aecdc3e4ce7a0dc43c65a16b427d6caa5504b10b51384f6b0bc703af646b09f5f1caeb6827b37d4480ce350ca8006204c850785f2810b","src":"https://erratique.ch/software/cmdliner/releases/cmdliner-1.2.0.tbz"}},"version":"1.2.0"},"cohttp":{"authors":["Anil Madhavapeddy","Stefano Zacchiroli","David Sheets","Thomas Gazagnaire","David Scott","Rudi Grinberg","Andy Ray","Anurag Soni"],"available":{"lhs":{"id":"opam-version"},"relop":"geq","rhs":"2.1.0"},"bug-reports":"https://github.com/mirage/ocaml-cohttp/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@cohttp/runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"http"},{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.9.0","prefix_relop":"geq"}],"val":"re"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"uri"},"uri-sexp","sexplib0",{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"stringext",{"conditions":[{"arg":"3.1.0","prefix_relop":"geq"}],"val":"base64"},{"conditions":[{"id":"with-test"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nCohttp is an OCaml library for creating HTTP daemons. It has a portable\nHTTP parser, and implementations using various asynchronous programming\nlibraries.\n\nSee the cohttp-async, cohttp-lwt, cohttp-lwt-unix, cohttp-lwt-jsoo and\ncohttp-mirage libraries for concrete implementations for particular\ntargets.\n\nYou can implement other targets using the parser very easily. Look at the `IO`\nsignature in `lib/s.mli` and implement that in the desired backend.\n\nYou can activate some runtime debugging by setting `COHTTP_DEBUG` to any\nvalue, and all requests and responses will be written to stderr. Further\ndebugging of the connection layer can be obtained by setting `CONDUIT_DEBUG`\nto any value.\n","dev-repo":"git+https://github.com/mirage/ocaml-cohttp.git","doc":"https://mirage.github.io/ocaml-cohttp/","files-contents":{},"flags":[{"id":"avoid-version"}],"homepage":"https://github.com/mirage/ocaml-cohttp","isLocal":false,"license":"ISC","maintainer":["Anil Madhavapeddy <anil@recoil.org>"],"name":"cohttp","opam-version":"2.0","synopsis":"An OCaml library for HTTP clients and servers","url":{"section":{"checksum":["sha256=2f00d14832c1c13427c12007e5b45a8f121e06e46d556a76904359ab26c0cff6","sha512=342034580418d55e7b9657c09cf187c415e562fc041e8f5eaa489cfae08f60b98afcddbc77632b479755cdfb2d30b5653ed5250b5b7dbde01f0be93f4e828bcc"],"src":"https://github.com/mirage/ocaml-cohttp/releases/download/v6.0.0_alpha2/cohttp-6.0.0.alpha2.tbz"}},"version":"6.0.0~alpha2","x-commit-hash":"bc9c78549a32d49be5fb51589331da51e86de269"},"cohttp-lwt":{"authors":["Anil Madhavapeddy","Stefano Zacchiroli","David Sheets","Thomas Gazagnaire","David Scott","Rudi Grinberg","Andy Ray","Anurag Soni"],"available":{"lhs":{"id":"opam-version"},"relop":"geq","rhs":"2.1.0"},"bug-reports":"https://github.com/mirage/ocaml-cohttp/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@cohttp-lwt/runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"http"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"cohttp"},{"conditions":[{"arg":"5.4.0","prefix_relop":"geq"}],"val":"lwt"},"sexplib0",{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"logs",{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"uri"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nThis is a portable implementation of HTTP that uses the Lwt concurrency library\nto multiplex IO. It implements as much of the logic in an OS-independent way\nas possible, so that more specialised modules can be tailored for different\ntargets. For example, you can install `cohttp-lwt-unix` or `cohttp-lwt-jsoo`\nfor a Unix or JavaScript backend, or `cohttp-mirage` for the MirageOS unikernel\nversion of the library. All of these implementations share the same IO logic\nfrom this module.","dev-repo":"git+https://github.com/mirage/ocaml-cohttp.git","doc":"https://mirage.github.io/ocaml-cohttp/","files-contents":{},"flags":[{"id":"avoid-version"}],"homepage":"https://github.com/mirage/ocaml-cohttp","isLocal":false,"license":"ISC","maintainer":["Anil Madhavapeddy <anil@recoil.org>"],"name":"cohttp-lwt","opam-version":"2.0","synopsis":"CoHTTP implementation using the Lwt concurrency library","url":{"section":{"checksum":["sha256=2f00d14832c1c13427c12007e5b45a8f121e06e46d556a76904359ab26c0cff6","sha512=342034580418d55e7b9657c09cf187c415e562fc041e8f5eaa489cfae08f60b98afcddbc77632b479755cdfb2d30b5653ed5250b5b7dbde01f0be93f4e828bcc"],"src":"https://github.com/mirage/ocaml-cohttp/releases/download/v6.0.0_alpha2/cohttp-6.0.0.alpha2.tbz"}},"version":"6.0.0~alpha2","x-commit-hash":"bc9c78549a32d49be5fb51589331da51e86de269"},"cohttp-lwt-unix":{"authors":["Anil Madhavapeddy","Stefano Zacchiroli","David Sheets","Thomas Gazagnaire","David Scott","Rudi Grinberg","Andy Ray","Anurag Soni"],"bug-reports":"https://github.com/mirage/ocaml-cohttp/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"}}],"val":"@cohttp-lwt-unix/runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"http"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"cohttp"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"cohttp-lwt"},{"conditions":[{"arg":"1.1.0","prefix_relop":"geq"}],"val":"cmdliner"},{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"lwt"},{"conditions":[{"arg":"5.0.0","prefix_relop":"geq"}],"val":"conduit-lwt"},{"conditions":[{"arg":"5.0.0","prefix_relop":"geq"}],"val":"conduit-lwt-unix"},{"conditions":[{"arg":"0.8.2","prefix_relop":"geq"}],"val":"fmt"},"base-unix",{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"magic-mime","logs",{"conditions":[{"id":"with-test"}],"val":"ounit"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nAn implementation of an HTTP client and server using the Lwt\nconcurrency library. See the `Cohttp_lwt_unix` module for information\non how to use this. The package also installs `cohttp-curl-lwt`\nand a `cohttp-server-lwt` binaries for quick uses of a HTTP(S)\nclient and server respectively.\n\nAlthough the name implies that this only works under Unix, it\nshould also be fine under Windows too.\n","dev-repo":"git+https://github.com/mirage/ocaml-cohttp.git","doc":"https://mirage.github.io/ocaml-cohttp/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-cohttp","isLocal":false,"license":"ISC","maintainer":["Anil Madhavapeddy <anil@recoil.org>"],"name":"cohttp-lwt-unix","opam-version":"2.0","synopsis":"CoHTTP implementation for Unix and Windows using Lwt","url":{"section":{"checksum":["sha256=2f00d14832c1c13427c12007e5b45a8f121e06e46d556a76904359ab26c0cff6","sha512=342034580418d55e7b9657c09cf187c415e562fc041e8f5eaa489cfae08f60b98afcddbc77632b479755cdfb2d30b5653ed5250b5b7dbde01f0be93f4e828bcc"],"src":"https://github.com/mirage/ocaml-cohttp/releases/download/v6.0.0_alpha2/cohttp-6.0.0.alpha2.tbz"}},"version":"6.0.0~alpha2","x-commit-hash":"bc9c78549a32d49be5fb51589331da51e86de269"},"conduit":{"authors":["Anil Madhavapeddy","Thomas Leonard","Thomas Gazagnaire","Rudi Grinberg"],"bug-reports":"https://github.com/mirage/ocaml-conduit/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"sexplib","astring","uri",{"conditions":[{"arg":"0.5.0","prefix_relop":"geq"}],"val":"logs"},{"conditions":[{"arg":"4.0.0","prefix_relop":"geq"}],"val":"ipaddr"},"ipaddr-sexp"],"description":"\nThe `conduit` library takes care of establishing and listening for\nTCP and SSL/TLS connections for the Lwt and Async libraries.\n\nThe reason this library exists is to provide a degree of abstraction\nfrom the precise SSL library used, since there are a variety of ways\nto bind to a library (e.g. the C FFI, or the Ctypes library), as well\nas well as which library is used (just OpenSSL for now).\n\nBy default, OpenSSL is used as the preferred connection library, but\nyou can force the use of the pure OCaml TLS stack by setting the\nenvironment variable `CONDUIT_TLS=native` when starting your program.\n\nThe useful opam packages available that extend this library are:\n\n- `conduit`: the main `Conduit` module\n- `conduit-lwt`: the portable Lwt implementation\n- `conduit-lwt-unix`: the Lwt/Unix implementation\n- `conduit-async` the Jane Street Async implementation\n- `conduit-mirage`: the MirageOS compatible implementation\n","dev-repo":"git+https://github.com/mirage/ocaml-conduit.git","doc":"https://mirage.github.io/ocaml-conduit/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-conduit","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"conduit","opam-version":"2.0","synopsis":"A network connection establishment library","tags":"org:mirage","url":{"section":{"checksum":["sha256=59d5e7b62437be489b0b79ce11ff90ac04ef39c683e4cefca8587afdc2f55bbb","sha512=c8e12d843d73cc776850f1b77e805380ac64f6c81b7bc4516befdeacf4785aeb638a0ccc62d7c1990c66edda6bf679c59c93210ffefeafed9a5fa3ec1bfedeca"],"src":"https://github.com/mirage/ocaml-conduit/releases/download/v6.2.1/conduit-6.2.1.tbz"}},"version":"6.2.1","x-commit-hash":"2977ef8b910d8283f6bd7f96305af5006ee7c7dd"},"conduit-lwt":{"authors":["Anil Madhavapeddy","Thomas Leonard","Thomas Gazagnaire","Rudi Grinberg"],"bug-reports":"https://github.com/mirage/ocaml-conduit/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"base-unix",{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"sexplib",{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"conduit"},{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"lwt"}],"dev-repo":"git+https://github.com/mirage/ocaml-conduit.git","files-contents":{},"homepage":"https://github.com/mirage/ocaml-conduit","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"conduit-lwt","opam-version":"2.0","synopsis":"A portable network connection establishment library using Lwt","tags":"org:mirage","url":{"section":{"checksum":["sha256=59d5e7b62437be489b0b79ce11ff90ac04ef39c683e4cefca8587afdc2f55bbb","sha512=c8e12d843d73cc776850f1b77e805380ac64f6c81b7bc4516befdeacf4785aeb638a0ccc62d7c1990c66edda6bf679c59c93210ffefeafed9a5fa3ec1bfedeca"],"src":"https://github.com/mirage/ocaml-conduit/releases/download/v6.2.1/conduit-6.2.1.tbz"}},"version":"6.2.1","x-commit-hash":"2977ef8b910d8283f6bd7f96305af5006ee7c7dd"},"conduit-lwt-unix":{"authors":["Anil Madhavapeddy","Thomas Leonard","Thomas Gazagnaire","Rudi Grinberg"],"bug-reports":"https://github.com/mirage/ocaml-conduit/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"conflicts":[{"conditions":[{"arg":"0.16.0","prefix_relop":"lt"}],"val":"tls-lwt"},{"conditions":[{"arg":"0.5.12","prefix_relop":"lt"}],"val":"ssl"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"base-unix","logs",{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"conduit-lwt"},{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"lwt"},{"conditions":[{"arg":"1.9.4","prefix_relop":"geq"}],"val":"uri"},{"conditions":[{"arg":"4.0.0","prefix_relop":"geq"}],"val":"ipaddr"},"ipaddr-sexp","ca-certs",{"conditions":[{"id":"with-test"}],"val":"lwt_log"},{"conditions":[{"id":"with-test"}],"val":"ssl"},{"conditions":[{"id":"with-test"}],"val":"lwt_ssl"}],"depopts":["tls-lwt","lwt_ssl","launchd"],"dev-repo":"git+https://github.com/mirage/ocaml-conduit.git","files-contents":{},"homepage":"https://github.com/mirage/ocaml-conduit","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"conduit-lwt-unix","opam-version":"2.0","synopsis":"A network connection establishment library for Lwt_unix","tags":"org:mirage","url":{"section":{"checksum":["sha256=59d5e7b62437be489b0b79ce11ff90ac04ef39c683e4cefca8587afdc2f55bbb","sha512=c8e12d843d73cc776850f1b77e805380ac64f6c81b7bc4516befdeacf4785aeb638a0ccc62d7c1990c66edda6bf679c59c93210ffefeafed9a5fa3ec1bfedeca"],"src":"https://github.com/mirage/ocaml-conduit/releases/download/v6.2.1/conduit-6.2.1.tbz"}},"version":"6.2.1","x-commit-hash":"2977ef8b910d8283f6bd7f96305af5006ee7c7dd"},"conf-gmp":{"authors":"nbraud","bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"win32"}}],"val":["sh","-exc","cc -c $CFLAGS -I/usr/local/include test.c"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"cygwinports"}}],"val":["sh","-exc","$(ocamlc -config-var c_compiler) -c $CFLAGS -I/usr/local/include test.c"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"}],"val":["sh","-exc","cc -c $CFLAGS -I/opt/homebrew/include -I/opt/local/include -I/usr/local/include test.c"]}],"depexts":[{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"debian"}],"val":["libgmp-dev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"ubuntu"}],"val":["libgmp-dev"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}}],"val":["gmp"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"macports"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"}}],"val":["gmp"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"centos"}],"val":["gmp","gmp-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"fedora"}],"val":["gmp","gmp-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"ol"}],"val":["gmp","gmp-devel"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"openbsd"}],"val":["gmp"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"freebsd"}],"val":["gmp"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"alpine"}],"val":["gmp-dev"]},{"conditions":[{"lhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"suse"},"logop":"or","rhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"opensuse"}}],"val":["gmp-devel"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"cygwinports"}}],"val":["gmp"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"nixos"}],"val":["gmp"]}],"description":"This package can only install if the GMP lib is installed on the system.","extra-files":["test.c","md5=2fd2970c293c36222a6d299ec155823f"],"files-contents":{"test.c":"#include <gmp.h>\n#ifndef __GMP_H__\n#error \"No GMP header\"\n#endif\n\nvoid test(void) {\n mpz_t n;\n mpz_init(n);\n mpz_clear(n);\n}\n"},"flags":{"id":"conf"},"homepage":"http://gmplib.org/","isLocal":false,"license":"GPL-1.0-or-later","maintainer":"nbraud","name":"conf-gmp","opam-version":"2.0","synopsis":"Virtual package relying on a GMP lib system installation","version":"4"},"conf-gmp-powm-sec":{"authors":"Etienne Millon <etienne@cryptosense.com>","bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[{"conditions":[{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"}],"val":["sh","-exc","cc -c $CFLAGS -I/usr/local/include test.c"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"}],"val":["sh","-exc","cc -c $CFLAGS -I/opt/homebrew/include -I/opt/local/include -I/usr/local/include test.c"]}],"depends":["conf-gmp"],"description":"\nThis package can only install if the GMP lib is installed on the system and\ncorresponds to a version that has the mpz_powm_sec function.","extra-files":["test.c","md5=29317f477fa828e18428660ef31064fb"],"files-contents":{"test.c":"#include <gmp.h>\n#ifndef __GMP_H__\n#error \"No GMP header\"\n#endif\n#if __GNU_MP_VERSION < 5\n#error \"GMP >= 5 is required to support mpz_powm_sec\"\n#endif\n\nvoid test(void) {\n mpz_t base;\n mpz_t exp;\n mpz_t mod;\n mpz_t rop;\n\n mpz_init_set_ui(base, 2u);\n mpz_init_set_ui(exp, 4u);\n mpz_init_set_ui(mod, 3u);\n mpz_init(rop);\n\n mpz_powm_sec(rop, base, exp, mod);\n\n mpz_clear(base);\n mpz_clear(exp);\n mpz_clear(mod);\n mpz_clear(rop);\n}\n"},"flags":{"id":"conf"},"homepage":"http://gmplib.org/","isLocal":false,"license":"GPL-1.0-or-later","maintainer":"Etienne Millon <etienne@cryptosense.com>","name":"conf-gmp-powm-sec","opam-version":"2.0","synopsis":"Virtual package relying on a GMP lib with constant-time modular exponentiation","version":"3"},"conf-libev":{"authors":"Marc Lehmann","bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[["sh","./build.sh"]],"depends":[{"conditions":[{"arg":"3.11.0","prefix_relop":"geq"}],"val":"ocaml"}],"depexts":[{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"debian"}],"val":["libev-dev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"ubuntu"}],"val":["libev-dev"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}}],"val":["libev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"alpine"}],"val":["libev-dev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"arch"}],"val":["libev"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"fedora"}],"val":["libev-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"rhel"}],"val":["libev-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"centos"}],"val":["libev-devel"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"ol"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"geq","rhs":"8"}}],"val":["libev-devel"]},{"conditions":[{"lhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"suse"},"logop":"or","rhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"opensuse"}}],"val":["libev-devel"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"freebsd"}],"val":["libev"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"openbsd"}],"val":["libev"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"nixos"}],"val":["libev"]}],"description":"\nLibev is modelled (very loosely) after libevent and the Event perl\nmodule, but is faster, scales better and is more correct, and also more\nfeatureful. And also smaller. Yay.","extra-files":[["discover.ml","md5=a734be402679b0ccf7c8aa60fc18bf9a"],["build.sh","md5=f37b5eb73ebeb177dff1cd8bb2f38c4e"]],"files-contents":{"build.sh":"#!/bin/sh\n\nocaml discover.ml\n","discover.ml":"(* Lightweight thread library for Objective Caml\n * http://www.ocsigen.org/lwt\n * Program discover\n * Copyright (C) 2010 Jérémie Dimino\n *\n * This program is free software; you can redistribute it and/or modify\n * it under the terms of the GNU Lesser General Public License as\n * published by the Free Software Foundation, with linking exceptions;\n * either version 2.1 of the License, or (at your option) any later\n * version. See COPYING file for details.\n *\n * This program is distributed in the hope that it will be useful, but\n * WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU\n * Lesser General Public License for more details.\n *\n * You should have received a copy of the GNU Lesser General Public\n * License along with this program; if not, write to the Free Software\n * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA\n * 02111-1307, USA.\n *)\n\n(* Discover available features *)\n\nlet cut_tail l = List.rev (List.tl (List.rev l))\n\nlet string_split sep source =\n let copy_part index offset =\n String.sub source index (offset - index)\n in\n let l = String.length source in\n let rec loop prev current acc =\n if current >= l then\n List.rev acc\n else\n match (source.[current] = sep, current = prev, current = l - 1) with\n | (true, true, _) -> loop (current + 1) (current + 1) acc\n | (true, _, _) -> loop (current + 1) (current + 1) ((copy_part prev current)::acc)\n | (false, _, true) -> loop (current + 1) (current + 1) ((copy_part prev (current + 1))::acc)\n | _ -> loop prev (current + 1) acc\n in loop 0 0 []\n\nlet uniq lst =\n let unique_set = Hashtbl.create (List.length lst) in\n List.iter (fun x -> Hashtbl.replace unique_set x ()) lst;\n Hashtbl.fold (fun x () xs -> x :: xs) unique_set []\n\nlet get_paths env_name =\n try\n let paths = Sys.getenv env_name in\n let dirs = string_split ':' paths in\n List.map (fun dir ->\n let components = string_split '/' dir in\n \"/\" ^ (String.concat \"/\" (cut_tail components))\n ) dirs\n with Not_found -> []\n\nlet env_paths = List.append (get_paths \"LIBRARY_PATH\") (get_paths \"C_INCLUDE_PATH\")\n\n(* Keep that in sync with the list in myocamlbuild.ml *)\nlet search_paths = uniq (List.append [\n \"/usr\";\n \"/usr/local\";\n \"/opt\";\n \"/opt/local\";\n \"/opt/homebrew\";\n \"/sw\";\n \"/mingw\";] env_paths)\n\nopen Printf\n\n(* +-----------------------------------------------------------------+\n | Test codes |\n +-----------------------------------------------------------------+ *)\n\nlet caml_code = \"\nexternal test : unit -> unit = \\\"lwt_test\\\"\nlet () = test ()\n\"\n\n\nlet libev_code = \"\n#include <caml/mlvalues.h>\n#include <ev.h>\n\nCAMLprim value lwt_test()\n{\n ev_default_loop(0);\n return Val_unit;\n}\n\"\n(* +-----------------------------------------------------------------+\n | Compilation |\n +-----------------------------------------------------------------+ *)\n\nlet ocamlc = ref \"ocamlc\"\nlet ext_obj = ref \".o\"\nlet exec_name = ref \"a.out\"\n\nlet log_file = ref \"\"\nlet caml_file = ref \"\"\n\n(* Search for a header file in standard directories. *)\nlet search_header header =\n let rec loop = function\n | [] ->\n None\n | dir :: dirs ->\n if Sys.file_exists (dir ^ \"/include/\" ^ header) then\n Some dir\n else\n loop dirs\n in\n loop search_paths\n\nlet c_args =\n let flags path = Printf.sprintf \"-ccopt -I%s/include -ccopt -L%s/lib\" path path in\n match search_header \"ev.h\" with\n | None -> \"\"\n | Some path -> flags path\n\nlet compile c_args args stub_file =\n let cmd = sprintf \"%s -custom %s %s %s %s > %s 2>&1\"\n !ocamlc\n c_args\n (Filename.quote stub_file)\n args\n (Filename.quote !caml_file)\n (Filename.quote !log_file) in\n Sys.command cmd = 0\n\nlet safe_remove file_name =\n try\n Sys.remove file_name\n with exn ->\n ()\n\nlet test_code args stub_code =\n let stub_file, oc = Filename.open_temp_file \"lwt_stub\" \".c\" in\n let cleanup () =\n safe_remove stub_file;\n safe_remove (Filename.chop_extension (Filename.basename stub_file) ^ !ext_obj)\n in\n try\n output_string oc stub_code;\n flush oc;\n close_out oc;\n let result = compile \"\" args stub_file || compile c_args args stub_file in\n cleanup ();\n result\n with exn ->\n (try close_out oc with _ -> ());\n cleanup ();\n raise exn\n\nlet config = open_out \"lwt_config.h\"\nlet config_ml = open_out \"lwt_config.ml\"\n\nlet test_feature ?(do_check = true) name macro ?(args=\"\") code =\n if do_check then begin\n printf \"testing for %s:%!\" name;\n if test_code args code then begin\n fprintf config \"#define %s\\n\" macro;\n fprintf config_ml \"#let %s = true\\n\" macro;\n printf \" %s available\\n%!\" (String.make (34 - String.length name) '.');\n true\n end else begin\n fprintf config \"//#define %s\\n\" macro;\n fprintf config_ml \"#let %s = false\\n\" macro;\n printf \" %s unavailable\\n%!\" (String.make (34 - String.length name) '.');\n false\n end\n end else begin\n printf \"not checking for %s\\n%!\" name;\n fprintf config \"//#define %s\\n\" macro;\n fprintf config_ml \"#let %s = false\\n\" macro;\n true\n end\n\n(* +-----------------------------------------------------------------+\n | Entry point |\n +-----------------------------------------------------------------+ *)\n\nlet () =\n let args = [\n \"-ocamlc\", Arg.Set_string ocamlc, \"<path> ocamlc\";\n \"-ext-obj\", Arg.Set_string ext_obj, \"<ext> C object files extension\";\n \"-exec-name\", Arg.Set_string exec_name, \"<name> name of the executable produced by ocamlc\";\n ] in\n Arg.parse args ignore \"check for external C libraries and available features\\noptions are:\";\n\n (* Put the caml code into a temporary file. *)\n let file, oc = Filename.open_temp_file \"lwt_caml\" \".ml\" in\n caml_file := file;\n output_string oc caml_code;\n close_out oc;\n\n log_file := Filename.temp_file \"lwt_output\" \".log\";\n\n (* Cleanup things on exit. *)\n at_exit (fun () ->\n (try close_out config with _ -> ());\n (try close_out config_ml with _ -> ());\n safe_remove !log_file;\n safe_remove !exec_name;\n safe_remove !caml_file;\n safe_remove (Filename.chop_extension !caml_file ^ \".cmi\");\n safe_remove (Filename.chop_extension !caml_file ^ \".cmo\"));\n\n let missing = [] in\n let missing = if test_feature \"libev\" \"HAVE_LIBEV\" ~args:\"-cclib -lev\" libev_code then missing else \"libev\" :: missing in\n\n if missing <> [] then begin\n printf \"\n The following recquired C libraries are missing: %s.\nPlease install them and retry. If they are installed in a non-standard location, set the environment variables C_INCLUDE_PATH and LIBRARY_PATH accordingly and retry.\n\nFor example, if they are installed in /opt/local, you can type:\n\nexport C_INCLUDE_PATH=/opt/local/include\nexport LIBRARY_PATH=/opt/local/lib\n\nTo compile without libev support, use ./configure --disable-libev ...\n\" (String.concat \", \" missing);\n exit 1\n end;\n\n(*\n ignore (test_feature \"eventfd\" \"HAVE_EVENTFD\" eventfd_code);\n ignore (test_feature \"fd passing\" \"HAVE_FD_PASSING\" fd_passing_code);\n ignore (test_feature \"sched_getcpu\" \"HAVE_GETCPU\" getcpu_code);\n ignore (test_feature \"affinity getting/setting\" \"HAVE_AFFINITY\" affinity_code);\n ignore (test_feature \"credentials getting\" \"HAVE_GET_CREDENTIALS\" get_credentials_code);\n ignore (test_feature \"fdatasync\" \"HAVE_FDATASYNC\" fdatasync_code)\n*)\n"},"flags":{"id":"conf"},"homepage":"http://software.schmorp.de/pkg/libev.html","isLocal":false,"license":"BSD-2-Clause","maintainer":"https://github.com/ocaml/opam-repository/issues","name":"conf-libev","opam-version":"2.0","synopsis":"High-performance event loop/event model with lots of features","version":"4-12"},"conf-libssl":{"authors":["The OpenSSL Project"],"bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[{"conditions":[{"lhs":{"lhs":{"lhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"freebsd"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"openbsd"}},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"netbsd"}},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"neq","rhs":"homebrew"}}],"val":["pkg-config","--print-errors","--exists","openssl"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}],"val":["sh","-ex","./homebrew.sh","check"]}],"build-env":[[{"lhs":{"id":"HOMEBREW_NO_AUTO_UPDATE"},"relop":"eq","rhs":"1"}]],"depends":[{"conditions":[{"id":"build"}],"val":"conf-pkg-config"}],"depexts":[{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"debian"}],"val":["libssl-dev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"ubuntu"}],"val":["libssl-dev"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"centos"}],"val":["openssl-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"ol"}],"val":["openssl-devel"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"fedora"}],"val":["openssl-devel"]},{"conditions":[{"lhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"suse"},"logop":"or","rhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"opensuse"}}],"val":["libopenssl-devel"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"alpine"}],"val":["openssl-dev"]},{"conditions":[{"lhs":{"id":"os-family"},"relop":"eq","rhs":"arch"}],"val":["openssl"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}],"val":["openssl"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"macports"}],"val":["openssl"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"nixos"}],"val":["openssl"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"cygwinports"}}],"val":["openssl"]}],"description":"This package can only install if the OpenSSL library is installed on the system.","extra-files":["homebrew.sh","md5=f5db8e7d51e159bc85f0d44cc13f9dbd"],"files-contents":{"homebrew.sh":"#!/bin/sh -ex\n\n# check the openssl installation\n# and symlink the homebrew pkg-config files for openssl to the opam local pkgconfig directory\n\nbrew_pkg_config=$(brew --prefix openssl)/lib/pkgconfig\n\ncase \"$1\" in\n check)\n if test \"$#\" != 1; then\n echo \"Usage: $0 check\"\n exit 1\n fi\n export PKG_CONFIG_PATH=\"$brew_pkg_config:$PKG_CONFIG_PATH\"\n pkg-config --print-errors --exists openssl\n ;;\n install)\n if test \"$#\" != 2; then\n echo \"Usage: $0 install <libdir>\"\n exit 1\n fi\n for fpath in \"$brew_pkg_config\"/*.pc; do\n test -e \"$fpath\" || break\n fname=$(basename \"$fpath\")\n tdir=\"$2/pkgconfig\"\n mkdir -p \"$tdir\"\n ln -s \"$fpath\" \"$tdir/$fname\"\n done\n ;;\n *)\n echo \"Usage: $0 <check|install>\"\n exit 1\n ;;\nesac\n"},"flags":{"id":"conf"},"homepage":"https://www.openssl.org/","install":[{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}],"val":["sh","-ex","./homebrew.sh","install",{"id":"lib"}]}],"isLocal":false,"license":"Apache-1.0","maintainer":"David Sheets <sheets@alum.mit.edu>","name":"conf-libssl","opam-version":"2.0","synopsis":"Virtual package relying on an OpenSSL library system installation","version":"4"},"conf-pkg-config":{"authors":["Francois Berenger"],"bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[{"conditions":[{"lhs":{"id":"os"},"relop":"neq","rhs":"openbsd"}],"val":["pkg-config","--help"]}],"depexts":[{"conditions":[{"lhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"debian"},"logop":"or","rhs":{"lhs":{"id":"os-family"},"relop":"eq","rhs":"ubuntu"}}],"val":["pkg-config"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"arch"}],"val":["pkgconf"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"fedora"}],"val":["pkgconf-pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"centos"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"leq","rhs":"7"}}],"val":["pkgconfig"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"mageia"}],"val":["pkgconf-pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"rhel"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"leq","rhs":"7"}}],"val":["pkgconfig"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"ol"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"leq","rhs":"7"}}],"val":["pkgconfig"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"alpine"}],"val":["pkgconf"]},{"conditions":[{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"nixos"}],"val":["pkgconfig"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}}],"val":["pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"macports"}}],"val":["pkgconfig"]},{"conditions":[{"lhs":{"id":"os"},"relop":"eq","rhs":"freebsd"}],"val":["pkgconf"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"rhel"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"geq","rhs":"8"}}],"val":["pkgconf-pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"centos"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"geq","rhs":"8"}}],"val":["pkgconf-pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"ol"},"logop":"and","rhs":{"lhs":{"id":"os-version"},"relop":"geq","rhs":"8"}}],"val":["pkgconf-pkg-config"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"cygwinports"}}],"val":["system:pkgconf"]}],"description":"\nThis package can only install if the pkg-config package is installed\non the system.","files-contents":{},"flags":{"id":"conf"},"homepage":"http://www.freedesktop.org/wiki/Software/pkg-config/","isLocal":false,"license":"GPL-1.0-or-later","maintainer":"unixjunkie@sdf.org","name":"conf-pkg-config","opam-version":"2.0","synopsis":"Check if pkg-config is installed and create an opam switch local pkgconfig folder","version":"3"},"containers":{"authors":["c-cube"],"bug-reports":"https://github.com/c-cube/ocaml-containers/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-doc"}],"val":["dune","build","@doc","-p",{"id":"name"}]},{"conditions":[{"lhs":{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"x86_32"}},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"arm32"}}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"2.9","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},"either","dune-configurator",{"conditions":[{"lhs":{"arg":"0.18","prefix_relop":"geq"},"logop":"and","rhs":{"id":"with-test"}}],"val":"qcheck-core"},{"conditions":[{"id":"with-test"}],"val":"yojson"},{"conditions":[{"id":"with-test"}],"val":"iter"},{"conditions":[{"id":"with-test"}],"val":"gen"},{"conditions":[{"id":"with-test"}],"val":"csexp"},{"conditions":[{"id":"with-test"}],"val":"uutf"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"depopts":["base-unix","base-threads"],"dev-repo":"git+https://github.com/c-cube/ocaml-containers.git","files-contents":{},"homepage":"https://github.com/c-cube/ocaml-containers/","isLocal":false,"license":"BSD-2-Clause","maintainer":["c-cube"],"name":"containers","opam-version":"2.0","synopsis":"A modular, clean and powerful extension of the OCaml standard library","tags":["stdlib","containers","iterators","list","heap","queue"],"url":{"section":{"checksum":["sha256=372df86e2a41e86c959c28a3392eb2ffd89754d1e5af2aaa09537654af57b1da","sha512=7d87d44065612095fa0342a9c95a2c4cfdf73d5af47c6fce24262cf2870c36dee70ebecd056113aa9c1643256bc032c08530f5083061c44602c0da5a132c2d6c"],"src":"https://github.com/c-cube/ocaml-containers/releases/download/v3.13/containers-3.13.tbz"}},"version":"3.13","x-commit-hash":"7c1ca1d82f3894bbfb634cbd421f696e854cafbc"},"cppo":{"authors":"Martin Jambon","bug-reports":"https://github.com/ocaml-community/cppo/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]},{"conditions":[{"id":"with-doc"}],"val":["dune","build","-p",{"id":"name"},"@doc"]}],"depends":[{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.10","prefix_relop":"geq"}],"val":"dune"},"base-unix"],"description":"Cppo is an equivalent of the C preprocessor for OCaml programs.\nIt allows the definition of simple macros and file inclusion.\n\nCppo is:\n\n* more OCaml-friendly than cpp\n* easy to learn without consulting a manual\n* reasonably fast\n* simple to install and to maintain","dev-repo":"git+https://github.com/ocaml-community/cppo.git","doc":"https://ocaml-community.github.io/cppo","files-contents":{},"homepage":"https://github.com/ocaml-community/cppo","isLocal":false,"license":"BSD-3-Clause","maintainer":["Martin Jambon <martin@mjambon.com>","Yishuai Li <yishuai@upenn.edu>"],"name":"cppo","opam-version":"2.0","synopsis":"Code preprocessor like cpp for OCaml","url":{"section":{"checksum":["md5=d23ffe85ac7dc8f0afd1ddf622770d09","sha512=26ff5a7b7f38c460661974b23ca190f0feae3a99f1974e0fd12ccf08745bd7d91b7bc168c70a5385b837bfff9530e0e4e41cf269f23dd8cf16ca658008244b44"],"src":"https://github.com/ocaml-community/cppo/archive/v1.6.9.tar.gz"}},"version":"1.6.9"},"crunch":{"authors":["Anil Madhavapeddy","Thomas Gazagnaire","Stefanie Schirmer","Hannes Mehnert"],"bug-reports":"https://github.com/mirage/ocaml-crunch/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"conflicts":[{"conditions":[{"arg":"3.0.0","prefix_relop":"lt"}],"val":"mirage-kv"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.1","prefix_relop":"geq"}],"val":"cmdliner"},"ptime",{"conditions":[{"arg":"2.5","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"lwt"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"3.0.0","prefix_relop":"geq"}}],"val":"mirage-kv"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"3.0.0","prefix_relop":"geq"}}],"val":"mirage-kv-mem"},{"conditions":[{"id":"with-test"}],"val":"fmt"}],"description":"\n`ocaml-crunch` takes a directory of files and compiles them into a standalone\nOCaml module which serves the contents directly from memory. This can be\nconvenient for libraries that need a few embedded files (such as a web server)\nand do not want to deal with all the trouble of file configuration.\n","dev-repo":"git+https://github.com/mirage/ocaml-crunch.git","doc":"https://mirage.github.io/ocaml-crunch/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-crunch","isLocal":false,"license":"ISC","maintainer":"MirageOS team","name":"crunch","opam-version":"2.0","synopsis":"Convert a filesystem into a static OCaml module","tags":["org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=2c5ba0d4110bcbb7731cba4eafb6c44a7487c3f88c1ad47401271b69ffa8ed6a","sha512=5aaa1b67456dd2f5e3ab450ea547e62fba2b0341a49f3b24669162dce91b6ea1158c1594d60c6df3e416e719484411c50ae61017c40b2f75ee90401aa543bd08"],"src":"https://github.com/mirage/ocaml-crunch/releases/download/v3.3.1/crunch-3.3.1.tbz"}},"version":"3.3.1","x-commit-hash":"bd4f0195b35c602b8b83886bc8731e649b1e3f9c"},"csexp":{"authors":["Quentin Hocquet <mefyl@gruntech.org>","Jane Street Group, LLC <opensource@janestreet.com>","Jeremie Dimino <jeremie@dimino.org>"],"bug-reports":"https://github.com/ocaml-dune/csexp/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.4","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\n\nThis library provides minimal support for Canonical S-expressions\n[1]. Canonical S-expressions are a binary encoding of S-expressions\nthat is super simple and well suited for communication between\nprograms.\n\nThis library only provides a few helpers for simple applications. If\nyou need more advanced support, such as parsing from more fancy input\nsources, you should consider copying the code of this library given\nhow simple parsing S-expressions in canonical form is.\n\nTo avoid a dependency on a particular S-expression library, the only\nmodule of this library is parameterised by the type of S-expressions.\n\n[1] https://en.wikipedia.org/wiki/Canonical_S-expressions\n","dev-repo":"git+https://github.com/ocaml-dune/csexp.git","doc":"https://ocaml-dune.github.io/csexp/","files-contents":{},"homepage":"https://github.com/ocaml-dune/csexp","isLocal":false,"license":"MIT","maintainer":["Jeremie Dimino <jeremie@dimino.org>"],"name":"csexp","opam-version":"2.0","synopsis":"Parsing and printing of S-expressions in Canonical form","url":{"section":{"checksum":["sha256=1a14dd04bb4379a41990248550628c77913a9c07f3c35c1370b6960e697787ff","sha512=be281018bcfc20d4db14894ef51c4b836d6338d2fdfe22e63d46f405f8dea7349e16f1c0ecd65f73d4c85a2a80e618cdbb8c9dafcbb9f229f04f1adca5b1973c"],"src":"https://github.com/ocaml-dune/csexp/releases/download/1.5.2/csexp-1.5.2.tbz"}},"version":"1.5.2","x-commit-hash":"e6c4768e10c61bcb04d09748744dad55602149c6"},"cstruct":{"authors":["Anil Madhavapeddy","Richard Mortier","Thomas Gazagnaire","Pierre Chambart","David Kaloper","Jeremy Yallop","David Scott","Mindy Preston","Thomas Leonard","Anton Kochkov","Etienne Millon"],"bug-reports":"https://github.com/mirage/ocaml-cstruct/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"3.5.0","prefix_relop":"lt"}],"val":"js_of_ocaml"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"arg":"0.8.9","prefix_relop":"geq"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"crowbar"}],"description":"\nCstruct is a library and syntax extension to make it easier to access C-like\nstructures directly from OCaml. It supports both reading and writing to these\nstructures, and they are accessed via the `Bigarray` module.","dev-repo":"git+https://github.com/mirage/ocaml-cstruct.git","doc":"https://mirage.github.io/ocaml-cstruct/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-cstruct","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"cstruct","opam-version":"2.0","synopsis":"Access C-like structures directly from OCaml","tags":["org:mirage","org:ocamllabs"],"url":{"section":{"checksum":["sha256=9a78073392580e8349148fa3ab4b1b2e989dc9d30d07401b04c96b7c60f03e62","sha512=8d33fe6b3707a3994d0225cd33cadde0bb2ca834ef01096e3df33a08e4a8c6d02ebccddf558a73988b8a5595b65fdc10de61efbf872c6c9e55c719c7e19c463d"],"src":"https://github.com/mirage/ocaml-cstruct/releases/download/v6.2.0/cstruct-6.2.0.tbz"}},"version":"6.2.0","x-commit-hash":"8c7c94a038aae72dc89c994551c9d2c690895607"},"decoders":{"authors":["Matt Bray <mattjbray@gmail.com>"],"bug-reports":"https://github.com/mattjbray/ocaml-decoders/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.1","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-doc"}],"val":"odoc"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.16","prefix_relop":"geq"}}],"val":"containers"}],"description":"A combinator library for \"decoding\" JSON-like values into your own Ocaml types, inspired by Elm's `Json.Decode` and `Json.Encode`.","dev-repo":"git+https://github.com/mattjbray/ocaml-decoders.git","doc":"https://mattjbray.github.io/ocaml-decoders/","files-contents":{},"homepage":"https://github.com/mattjbray/ocaml-decoders","isLocal":false,"license":"ISC","maintainer":["Matt Bray <mattjbray@gmail.com>"],"name":"decoders","opam-version":"2.0","synopsis":"Elm-inspired decoders for Ocaml","url":{"section":{"checksum":["sha256=47fe79c4102d0f710eff3ceaef313100d9df3c7945834d3cf38a39742a573597","sha512=6fe4e9f99d865fb24c8b1da08ba485282fc8eaf6ed48cedbe8109cae863ad441a95b2643b4ea217a6b012f149682ca69af436ed26a3d646903738fce5651a229"],"src":"https://github.com/mattjbray/ocaml-decoders/releases/download/v1.0.0/decoders-1.0.0.tbz"}},"version":"1.0.0","x-commit-hash":"0e0afb7e988aa746a1d6d7f1e8ee8ba2e875e382"},"decoders-yojson":{"authors":["Matt Bray <mattjbray@gmail.com>"],"bug-reports":"https://github.com/mattjbray/ocaml-decoders/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.1","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"decoders"},{"conditions":[{"arg":"1.6.0","prefix_relop":"geq"}],"val":"yojson"},{"conditions":[{"id":"with-doc"}],"val":"odoc"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.16","prefix_relop":"geq"}}],"val":"containers"},{"conditions":[{"id":"with-test"}],"val":"ounit2"}],"description":"A combinator library for \"decoding\" JSON-like values into your own Ocaml types, inspired by Elm's `Json.Decode` and `Json.Encode`.","dev-repo":"git+https://github.com/mattjbray/ocaml-decoders.git","doc":"https://mattjbray.github.io/ocaml-decoders/","files-contents":{},"homepage":"https://github.com/mattjbray/ocaml-decoders","isLocal":false,"license":"ISC","maintainer":["Matt Bray <mattjbray@gmail.com>"],"name":"decoders-yojson","opam-version":"2.0","synopsis":"Yojson backend for decoders","url":{"section":{"checksum":["sha256=47fe79c4102d0f710eff3ceaef313100d9df3c7945834d3cf38a39742a573597","sha512=6fe4e9f99d865fb24c8b1da08ba485282fc8eaf6ed48cedbe8109cae863ad441a95b2643b4ea217a6b012f149682ca69af436ed26a3d646903738fce5651a229"],"src":"https://github.com/mattjbray/ocaml-decoders/releases/download/v1.0.0/decoders-1.0.0.tbz"}},"version":"1.0.0","x-commit-hash":"0e0afb7e988aa746a1d6d7f1e8ee8ba2e875e382"},"digestif":{"authors":["Eyyüb Sari <eyyub.sari@epitech.eu>","Romain Calascibetta <romain.calascibetta@gmail.com>"],"bug-reports":"https://github.com/mirage/digestif/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"6.0.0","prefix_relop":"lt"}],"val":"mirage-xen"},"ocaml-freestanding"],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.6.0","prefix_relop":"geq"}],"val":"dune"},"eqaf",{"conditions":[{"id":"with-test"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"bos"},{"conditions":[{"id":"with-test"}],"val":"astring"},{"conditions":[{"id":"with-test"}],"val":"fpath"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"id":"with-test"}],"val":"ocamlfind"}],"description":"\nDigestif is a toolbox to provide hashes implementations in C and OCaml.\n\nIt uses the linking trick and user can decide at the end to use the C implementation or the OCaml implementation.\n\nWe provides implementation of:\n * MD5\n * SHA1\n * SHA224\n * SHA256\n * SHA384\n * SHA512\n * SHA3\n * Keccak-256\n * WHIRLPOOL\n * BLAKE2B\n * BLAKE2S\n * RIPEMD160\n","dev-repo":"git+https://github.com/mirage/digestif.git","doc":"https://mirage.github.io/digestif/","files-contents":{},"homepage":"https://github.com/mirage/digestif","install":[{"conditions":[{"id":"with-test"}],"val":["dune","install","-p",{"id":"name"}]},{"conditions":[{"id":"with-test"}],"val":["ocaml","./test/test_runes.ml"]}],"isLocal":false,"license":"MIT","maintainer":["Eyyüb Sari <eyyub.sari@epitech.eu>","Romain Calascibetta <romain.calascibetta@gmail.com>"],"name":"digestif","opam-version":"2.0","synopsis":"Hashes implementations (SHA*, RIPEMD160, BLAKE2* and MD5)","url":{"section":{"checksum":["sha256=c3793e720f0da8054f6286c545c821a7febe882e7f4e5497ec89b15a353511e1","sha512=a4014f65a3be370761833fd98f3916d0a64ada6f99ac016890f5ae98ec75a941836a5a1e145ae36372aeb6b48c66a0ad9907a4318bfc8dc0c237840edba1aef4"],"src":"https://github.com/mirage/digestif/releases/download/v1.1.4/digestif-1.1.4.tbz"}},"version":"1.1.4","x-commit-hash":"92160895c308d0d5b722afd4811882f7850277d2"},"domain-name":{"authors":"Hannes Mehnert <hannes@mehnert.org>","bug-reports":"https://github.com/hannesm/domain-name/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.04.2","prefix_relop":"geq"}],"val":"ocaml"},"dune",{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"\nA domain name is a sequence of labels separated by dots, such as `foo.example`.\nEach label may contain any bytes. The length of each label may not exceed 63\ncharactes. The total length of a domain name is limited to 253 (byte\nrepresentation is 255), but other protocols (such as SMTP) may apply even\nsmaller limits. A domain name label is case preserving, comparison is done in a\ncase insensitive manner.\n","dev-repo":"git+https://github.com/hannesm/domain-name.git","doc":"https://hannesm.github.io/domain-name/doc","files-contents":{},"homepage":"https://github.com/hannesm/domain-name","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"domain-name","opam-version":"2.0","synopsis":"RFC 1035 Internet domain names","url":{"section":{"checksum":["sha256=a5c06e22845895201973e812fe3019274d1db81c0a7873da6c8007c4ad2108c5","sha512=f25aedb1ddf6ab8c49b1545cf88f4990114a9e7954d91cabf260e6ce470abd42dd135e8a55084262a77d4c9ee4bff6dc00c71307b23a48d82d50593b910ee173"],"src":"https://github.com/hannesm/domain-name/releases/download/v0.4.0/domain-name-0.4.0.tbz"}},"version":"0.4.0","x-commit-hash":"e9833486ee40ef2c49c43dd72976022a627b4a34"},"dream":{"author":"Anton Bachin <antonbachin@yahoo.com>","bug-reports":"https://github.com/aantron/dream/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":["base-unix","bigarray-compat","camlp-streams",{"conditions":[{"lhs":{"arg":"1.8.0","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"2.0.0~","prefix_relop":"lt"}}],"val":"caqti"},"caqti-lwt",{"conditions":[{"lhs":{"id":"os"},"relop":"neq","rhs":"win32"}],"val":"conf-libev"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},{"conditions":[{"arg":"1.0.0~alpha2","prefix_relop":"geq"}],"val":"dream-httpaf"},{"conditions":[{"arg":"1.0.0~alpha2","prefix_relop":"geq"}],"val":"dream-pure"},{"conditions":[{"arg":"2.7.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},"graphql_parser","graphql-lwt","lwt",{"conditions":[{"arg":"1.2.2","prefix_relop":"geq"}],"val":"lwt_ppx"},"lwt_ssl",{"conditions":[{"arg":"0.5.0","prefix_relop":"geq"}],"val":"logs"},"magic-mime",{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"mirage-clock"},{"conditions":[{"arg":"0.8.1","prefix_relop":"geq"}],"val":"mirage-crypto"},"mirage-crypto-rng","mirage-crypto-rng-lwt",{"conditions":[{"arg":"0.4.0","prefix_relop":"geq"}],"val":"multipart_form"},"multipart_form-lwt",{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"0.8.1","prefix_relop":"geq"}],"val":"ptime"},{"conditions":[{"arg":"0.5.8","prefix_relop":"geq"}],"val":"ssl"},{"conditions":[{"arg":"4.2.0","prefix_relop":"geq"}],"val":"uri"},"yojson",{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"2.5.0","prefix_relop":"geq"}}],"val":"bisect_ppx"},{"conditions":[{"id":"with-test"}],"val":"caqti-driver-postgresql"},{"conditions":[{"id":"with-test"}],"val":"caqti-driver-sqlite3"},{"conditions":[{"id":"with-test"}],"val":"crunch"},{"conditions":[{"id":"with-test"}],"val":"js_of_ocaml"},{"conditions":[{"id":"with-test"}],"val":"js_of_ocaml-ppx"},{"conditions":[{"id":"with-test"}],"val":"lambdasoup"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.15.0","prefix_relop":"geq"}}],"val":"ppx_expect"},{"conditions":[{"id":"with-test"}],"val":"ppx_yojson_conv"},{"conditions":[{"id":"with-test"}],"val":"reason"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"4.5.0","prefix_relop":"geq"}}],"val":"tyxml"}],"description":"\nDream is a feature-complete Web framework with a simple programming\nmodel and no boilerplate. It provides only two data types, request and\nresponse.\n\nAlmost everything else is either a built-in OCaml type, or an\nabbreviation for a bare function. For example, a Web app, known in\nDream as a handler, is just an ordinary function from requests to\nresponses. And a middleware is then just a function from handlers to\nhandlers.\n\nWithin this model, Dream adds:\n\n- Session management with pluggable back ends.\n- A fully composable router.\n- Support for HTTP/1.1, HTTP/2, and HTTPS.\n- WebSockets.\n- GraphQL, including subscriptions and a built-in GraphiQL editor.\n- SQL connection pool helpers.\n- Server-side HTML templates.\n- Automatic secure handling of cookies and forms.\n- Unified, internationalization-friendly error handling.\n- A neat log, and OCaml runtime configuration.\n- Helpers for Web formats, such as Base64url, and a modern cipher.\n\nBecause of the simple programming model, everything is optional and\ncomposable. It is trivailly possible to strip Dream down to just a\nbare driver of the various HTTP protocols.\n\nDream is presented as a single module, whose API is documented on one\npage. In addition, Dream comes with a large number of examples.\nSecurity topics are introduced throughout, wherever they are\napplicable.","dev-repo":"git+https://github.com/aantron/dream.git","doc":"https://aantron.github.io/dream","files-contents":{},"homepage":"https://github.com/aantron/dream","isLocal":false,"license":"MIT","maintainer":"Anton Bachin <antonbachin@yahoo.com>","name":"dream","opam-version":"2.0","synopsis":"Tidy, feature-complete Web framework","tags":["http","web","framework","websocket","graphql","server","http2","tls"],"url":{"section":{"checksum":"md5=de6f6908ae899c9e85f2c751a0263932","src":"https://github.com/aantron/dream/releases/download/1.0.0-alpha5/dream-1.0.0-alpha5.tar.gz"}},"version":"1.0.0~alpha5"},"dream-httpaf":{"author":"Anton Bachin <antonbachin@yahoo.com>","bug-reports":"https://github.com/aantron/dream/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":["dream-pure",{"conditions":[{"arg":"2.7.0","prefix_relop":"geq"}],"val":"dune"},"lwt",{"conditions":[{"arg":"1.2.2","prefix_relop":"geq"}],"val":"lwt_ppx"},"lwt_ssl",{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"0.5.8","prefix_relop":"geq"}],"val":"ssl"},{"conditions":[{"arg":"0.14.0","prefix_relop":"geq"}],"val":"angstrom"},{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"base64"},{"conditions":[{"arg":"0.5.0","prefix_relop":"geq"}],"val":"bigstringaf"},{"conditions":[{"arg":"0.7.2","prefix_relop":"geq"}],"val":"digestif"},{"conditions":[{"arg":"0.6.1","prefix_relop":"geq"}],"val":"faraday"},"faraday-lwt-unix",{"conditions":[{"arg":"0.5","prefix_relop":"geq"}],"val":"ke"},{"conditions":[{"arg":"1.2.0","prefix_relop":"geq"}],"val":"lwt_ssl"},"psq","result"],"description":"This package does not have a stable API.","dev-repo":"git+https://github.com/aantron/dream.git","doc":"https://aantron.github.io/dream","files-contents":{},"homepage":"https://github.com/aantron/dream","isLocal":false,"license":"MIT","maintainer":"Anton Bachin <antonbachin@yahoo.com>","name":"dream-httpaf","opam-version":"2.0","synopsis":"Internal: shared http/af stack for Dream (server) and Hyper (client)","url":{"section":{"checksum":"md5=de6f6908ae899c9e85f2c751a0263932","src":"https://github.com/aantron/dream/releases/download/1.0.0-alpha5/dream-1.0.0-alpha5.tar.gz"}},"version":"1.0.0~alpha2"},"dream-pure":{"author":"Anton Bachin <antonbachin@yahoo.com>","bug-reports":"https://github.com/aantron/dream/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"3.1.0","prefix_relop":"geq"}],"val":"base64"},{"conditions":[{"arg":"0.5.0","prefix_relop":"geq"}],"val":"bigstringaf"},{"conditions":[{"arg":"2.7.0","prefix_relop":"geq"}],"val":"dune"},"hmap","lwt",{"conditions":[{"arg":"1.2.2","prefix_relop":"geq"}],"val":"lwt_ppx"},{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"0.8.1","prefix_relop":"geq"}],"val":"ptime"},{"conditions":[{"arg":"4.2.0","prefix_relop":"geq"}],"val":"uri"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"2.5.0","prefix_relop":"geq"}}],"val":"bisect_ppx"},{"conditions":[{"id":"with-test"}],"val":"ppx_expect"},{"conditions":[{"id":"with-test"}],"val":"ppx_yojson_conv"}],"description":"This package does not have a stable API.","dev-repo":"git+https://github.com/aantron/dream.git","doc":"https://aantron.github.io/dream","files-contents":{},"homepage":"https://github.com/aantron/dream","isLocal":false,"license":"MIT","maintainer":"Anton Bachin <antonbachin@yahoo.com>","name":"dream-pure","opam-version":"2.0","synopsis":"Internal: shared HTTP types for Dream (server) and Hyper (client)","url":{"section":{"checksum":"md5=20aaa93b13c210324e9dcceeba3c3b21","src":"https://github.com/aantron/dream/releases/download/1.0.0-alpha4/dream-1.0.0-alpha4.tar.gz"}},"version":"1.0.0~alpha2"},"dune":{"authors":["Jane Street Group, LLC <opensource@janestreet.com>"],"bug-reports":"https://github.com/ocaml/dune/issues","build":[["ocaml","boot/bootstrap.ml","-j",{"id":"jobs"}],["./_boot/dune.exe","build","dune.install","--release","--profile","dune-bootstrap","-j",{"id":"jobs"}]],"conflicts":[{"conditions":[{"arg":"3.4.0","prefix_relop":"lt"}],"val":"merlin"},{"conditions":[{"arg":"1.3.0","prefix_relop":"lt"}],"val":"ocaml-lsp-server"},{"conditions":[{"arg":"2.3.0","prefix_relop":"lt"}],"val":"dune-configurator"},{"conditions":[{"arg":"2.0.1","prefix_relop":"lt"}],"val":"odoc"},{"conditions":[{"arg":"1.3.0","prefix_relop":"lt"}],"val":"dune-release"},{"conditions":[{"arg":"3.6.0","prefix_relop":"lt"}],"val":"js_of_ocaml-compiler"},{"conditions":[{"arg":"transition","prefix_relop":"eq"}],"val":"jbuilder"}],"depends":[{"group":[{"lhs":{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},"logop":"or","rhs":{"group":[{"lhs":{"conditions":[{"lhs":{"arg":"4.02","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"4.08~~","prefix_relop":"lt"}}],"val":"ocaml"},"logop":"and","rhs":"ocamlfind-secondary"}]}}]},"base-unix","base-threads"],"description":"\n\nDune is a build system that was designed to simplify the release of\nJane Street packages. It reads metadata from \"dune\" files following a\nvery simple s-expression syntax.\n\nDune is fast, has very low-overhead, and supports parallel builds on\nall platforms. It has no system dependencies; all you need to build\ndune or packages using dune is OCaml. You don't need make or bash\nas long as the packages themselves don't use bash explicitly.\n\nDune is composable; supporting multi-package development by simply\ndropping multiple repositories into the same directory.\n\nDune also supports multi-context builds, such as building against\nseveral opam roots/switches simultaneously. This helps maintaining\npackages across several versions of OCaml and gives cross-compilation\nfor free.\n","dev-repo":"git+https://github.com/ocaml/dune.git","doc":"https://dune.readthedocs.io/","files-contents":{},"homepage":"https://github.com/ocaml/dune","isLocal":false,"license":"MIT","maintainer":["Jane Street Group, LLC <opensource@janestreet.com>"],"name":"dune","opam-version":"2.0","synopsis":"Fast, portable, and opinionated build system","url":{"section":{"checksum":["sha256=b9fd6560879f9d340ae8a87c967b0d2bcd3c4120cffcd9fb661f325078f74f6f","sha512=1a4159d18a7aee0ca9f53f176955a41f5a6d83b16885e7f6ac47326453572df74a87f21f4ceddb8d2e94e00f61d2ba5ca6dba299679968f1d151d2811dcd2014"],"src":"https://github.com/ocaml/dune/releases/download/3.12.1/dune-3.12.1.tbz"}},"version":"3.12.1","x-commit-hash":"2e4994f005e9a94993150601bdb60759d9de5ab6"},"dune-configurator":{"authors":["Jane Street Group, LLC <opensource@janestreet.com>"],"bug-reports":"https://github.com/ocaml/dune/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["rm","-rf","vendor/csexp"],["rm","-rf","vendor/pp"],["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.5","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.04.0","prefix_relop":"geq"}],"val":"ocaml"},"base-unix",{"conditions":[{"arg":"1.5.0","prefix_relop":"geq"}],"val":"csexp"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\ndune-configurator is a small library that helps writing OCaml scripts that\ntest features available on the system, in order to generate config.h\nfiles for instance.\nAmong other things, dune-configurator allows one to:\n- test if a C program compiles\n- query pkg-config\n- import #define from OCaml header files\n- generate config.h file\n","dev-repo":"git+https://github.com/ocaml/dune.git","doc":"https://dune.readthedocs.io/","files-contents":{},"homepage":"https://github.com/ocaml/dune","isLocal":false,"license":"MIT","maintainer":["Jane Street Group, LLC <opensource@janestreet.com>"],"name":"dune-configurator","opam-version":"2.0","synopsis":"Helper library for gathering system configuration","url":{"section":{"checksum":["sha256=b9fd6560879f9d340ae8a87c967b0d2bcd3c4120cffcd9fb661f325078f74f6f","sha512=1a4159d18a7aee0ca9f53f176955a41f5a6d83b16885e7f6ac47326453572df74a87f21f4ceddb8d2e94e00f61d2ba5ca6dba299679968f1d151d2811dcd2014"],"src":"https://github.com/ocaml/dune/releases/download/3.12.1/dune-3.12.1.tbz"}},"version":"3.12.1","x-commit-hash":"2e4994f005e9a94993150601bdb60759d9de5ab6"},"duration":{"authors":"Hannes Mehnert <hannes@mehnert.org>","bug-reports":"https://github.com/hannesm/duration/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.04.2","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.1","prefix_relop":"geq"}}],"val":"alcotest"}],"description":"\nA duration is represented in nanoseconds as an unsigned 64 bit integer. This\nhas a range of up to 584 years. Functions provided check the input and raise\non negative or out of bound input.\n","dev-repo":"git+https://github.com/hannesm/duration.git","doc":"https://hannesm.github.io/duration/doc","files-contents":{},"homepage":"https://github.com/hannesm/duration","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"duration","opam-version":"2.0","synopsis":"Conversions to various time units","url":{"section":{"checksum":["sha256=c738c1f38cfb99820c121cd3ddf819de4b2228f0d50eacbd1cc3ce99e7c71e2b","sha512=0de9e15c7d6188872ddd9994f08616c4a1822e4ac92724efa2c312fbb2fc44cd7cbe4b36bcf66a8451d510c1fc95de481760afbcacb8f83e183262595dcf5f0c"],"src":"https://github.com/hannesm/duration/releases/download/v0.2.1/duration-0.2.1.tbz"}},"version":"0.2.1","x-commit-hash":"6abe42ebe585a96f79eb91045911b9a73c1db19e"},"either":{"authors":["Craig Ferguson <me@craigfe.io>"],"bug-reports":"https://github.com/mirage/either/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nProjects that want to use the Either module defined in OCaml 4.12.0 while\nstaying compatible with older versions of OCaml should use this library\ninstead.\n","dev-repo":"git+https://github.com/mirage/either.git","doc":"https://mirage.github.io/either","files-contents":{},"homepage":"https://github.com/mirage/either","isLocal":false,"license":"MIT","maintainer":["Craig Ferguson <me@craigfe.io>"],"name":"either","opam-version":"2.0","synopsis":"Compatibility Either module","url":{"section":{"checksum":["sha256=bf674de3312dee7b7215f07df1e8a96eb3d679164b8a918cdd95b8d97e505884","sha512=147854c09f897dd028b18a9f19acea8666107aaa7b1aab3c92f568af531364f57298edcaf3897d74246d3857d52e9bfb7ad0fc39220d988d9f14694ca1d5e9ed"],"src":"https://github.com/mirage/either/releases/download/1.0.0/either-1.0.0.tbz"}},"version":"1.0.0","x-commit-hash":"a270ceac58e3e5bed6fe7e8bfb7132b14ee9c322"},"eqaf":{"authors":["Romain Calascibetta <romain.calascibetta@gmail.com>"],"bug-reports":"https://github.com/mirage/eqaf/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j","1","--no-buffer","--verbose"]}],"depends":[{"conditions":[{"arg":"4.07.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"1.1.0","prefix_relop":"geq"}],"val":"cstruct"},{"conditions":[{"id":"with-test"}],"val":"base64"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"crowbar"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.7","prefix_relop":"geq"}}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"bechamel"}],"description":"\nThis package provides an equal function on string in constant-time to avoid timing-attack with crypto stuff.\n","dev-repo":"git+https://github.com/mirage/eqaf.git","doc":"https://mirage.github.io/eqaf/","files-contents":{},"homepage":"https://github.com/mirage/eqaf","isLocal":false,"license":"MIT","maintainer":["Romain Calascibetta <romain.calascibetta@gmail.com>"],"name":"eqaf","opam-version":"2.0","synopsis":"Constant-time equal function on string","url":{"section":{"checksum":["sha256=ec0e28a946ac6817f95d5854f05a9961ae3a8408bb610e79cfad01b9b255dfe0","sha512=4df7fd3ea35156953a172c1a021aab05b8b122ee8d3cfdb34f96edb1b5133d1fe2721b90cb64287841d770b16c2ffe70559c66e90f8d61a92b73857da22548c4"],"src":"https://github.com/mirage/eqaf/releases/download/v0.9/eqaf-0.9.tbz"}},"version":"0.9","x-commit-hash":"e878ed56e40ca05c851a0e3297ab00ab76b10e0e"},"faraday":{"authors":["Spiros Eliopoulos <spiros@inhabitedtype.com>"],"bug-reports":"https://github.com/inhabitedtype/faraday/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.4.1","prefix_relop":"geq"}}],"val":"alcotest"},"bigstringaf"],"description":"\nFaraday is a library for writing fast and memory-efficient serializers. Its\ncore type and related operation gives the user fine-grained control over\ncopying and allocation behavior while serializing user-defined types, and\npresents the output in a form that makes it possible to use vectorized write\noperations, such as the writev system call, or any other platform or\napplication-specific output APIs.","dev-repo":"git+https://github.com/inhabitedtype/faraday.git","files-contents":{},"homepage":"https://github.com/inhabitedtype/faraday","isLocal":false,"license":"BSD-3-clause","maintainer":"Spiros Eliopoulos <spiros@inhabitedtype.com>","name":"faraday","opam-version":"2.0","synopsis":"A library for writing fast and memory-efficient serializers","url":{"section":{"checksum":"md5=307dccc4ea67ff0eeff394701d05bbe7","src":"https://github.com/inhabitedtype/faraday/archive/0.8.2.tar.gz"}},"version":"0.8.2"},"faraday-lwt":{"authors":["Spiros Eliopoulos <spiros@inhabitedtype.com>"],"bug-reports":"https://github.com/inhabitedtype/faraday/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.5.0","prefix_relop":"geq"}],"val":"faraday"},"lwt"],"dev-repo":"git+https://github.com/inhabitedtype/faraday.git","files-contents":{},"homepage":"https://github.com/inhabitedtype/faraday","isLocal":false,"license":"BSD-3-clause","maintainer":"Spiros Eliopoulos <spiros@inhabitedtype.com>","name":"faraday-lwt","opam-version":"2.0","synopsis":"Lwt support for Faraday","url":{"section":{"checksum":"md5=307dccc4ea67ff0eeff394701d05bbe7","src":"https://github.com/inhabitedtype/faraday/archive/0.8.2.tar.gz"}},"version":"0.8.2"},"faraday-lwt-unix":{"authors":["Spiros Eliopoulos <spiros@inhabitedtype.com>"],"bug-reports":"https://github.com/inhabitedtype/faraday/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},"faraday-lwt",{"conditions":[{"arg":"2.7.0","prefix_relop":"geq"}],"val":"lwt"},"base-unix"],"dev-repo":"git+https://github.com/inhabitedtype/faraday.git","files-contents":{},"homepage":"https://github.com/inhabitedtype/faraday","isLocal":false,"license":"BSD-3-clause","maintainer":"Spiros Eliopoulos <spiros@inhabitedtype.com>","name":"faraday-lwt-unix","opam-version":"2.0","synopsis":"Lwt_unix support for Faraday","url":{"section":{"checksum":"md5=307dccc4ea67ff0eeff394701d05bbe7","src":"https://github.com/inhabitedtype/faraday/archive/0.8.2.tar.gz"}},"version":"0.8.2"},"fmt":{"authors":["The fmt programmers"],"bug-reports":"https://github.com/dbuenzli/fmt/issues","build":[["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%","--with-base-unix","%{base-unix:installed}%","--with-cmdliner","%{cmdliner:installed}%"]],"conflicts":[{"conditions":[{"arg":"0.9.8","prefix_relop":"lt"}],"val":"cmdliner"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"}],"depopts":["base-unix","cmdliner"],"description":"\nFmt exposes combinators to devise `Format` pretty-printing functions.\n\nFmt depends only on the OCaml standard library. The optional `Fmt_tty`\nlibrary that allows to setup formatters for terminal color output\ndepends on the Unix library. The optional `Fmt_cli` library that\nprovides command line support for Fmt depends on [`Cmdliner`][cmdliner].\n\nFmt is distributed under the ISC license.\n\n[cmdliner]: http://erratique.ch/software/cmdliner\n\nHome page: http://erratique.ch/software/fmt","dev-repo":"git+https://erratique.ch/repos/fmt.git","doc":"https://erratique.ch/software/fmt/doc/","files-contents":{},"homepage":"https://erratique.ch/software/fmt","isLocal":false,"license":["ISC"],"maintainer":["Daniel Bünzli <daniel.buenzl i@erratique.ch>"],"name":"fmt","opam-version":"2.0","synopsis":"OCaml Format pretty-printer combinators","tags":["string","format","pretty-print","org:erratique"],"url":{"section":{"checksum":"sha512=66cf4b8bb92232a091dfda5e94d1c178486a358cdc34b1eec516d48ea5acb6209c0dfcb416f0c516c50ddbddb3c94549a45e4a6d5c5fd1c81d3374dec823a83b","src":"https://erratique.ch/software/fmt/releases/fmt-0.9.0.tbz"}},"version":"0.9.0"},"fpath":{"authors":["The fpath programmers"],"bug-reports":"https://github.com/dbuenzli/fpath/issues","build":[["ocaml","pkg/pkg.ml","build",{"conditions":[{"id":"dev"}],"val":"--dev-pkg=true"}]],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"0.9.0","prefix_relop":"geq"}}],"val":"topkg"},"astring"],"description":"\nFpath is an OCaml module for handling file system paths with POSIX or\nWindows conventions. Fpath processes paths without accessing the file\nsystem and is independent from any system library.\n\nFpath depends on [Astring][astring] and is distributed under the ISC\nlicense.\n\n[astring]: http://erratique.ch/software/astring\n","dev-repo":"git+https://erratique.ch/repos/fpath.git","doc":"https://erratique.ch/software/fpath/doc","files-contents":{},"homepage":"https://erratique.ch/software/fpath","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"fpath","opam-version":"2.0","synopsis":"File system paths for OCaml","tags":["file","system","path","org:erratique"],"url":{"section":{"archive":"https://erratique.ch/software/fpath/releases/fpath-0.7.3.tbz","checksum":"0740b530e8fed5b0adc5eee8463cfc2f"}},"version":"0.7.3"},"gmap":{"authors":"Hannes Mehnert <hannes@mehnert.org>","bug-reports":"https://github.com/hannesm/gmap/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.04.2","prefix_relop":"geq"}],"val":"ocaml"},"dune",{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"fmt"}],"description":"\nGmap exposes the functor `Make` which takes a key type (a\n[GADT](https://en.wikipedia.org/wiki/Generalized_algebraic_data_type) 'a key)\nand outputs a type-safe Map where each 'a key is associated with a 'a value.\nThis removes the need for additional packing. It uses OCaml's stdlib\n[Map](http://caml.inria.fr/pub/docs/manual-ocaml/libref/Map.html) data\nstructure.\n","dev-repo":"git+https://github.com/hannesm/gmap.git","doc":"https://hannesm.github.io/gmap/doc","files-contents":{},"homepage":"https://github.com/hannesm/gmap","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"gmap","opam-version":"2.0","synopsis":"Heterogenous maps over a GADT","url":{"section":{"checksum":["sha256=04dd9e6226ac8f8fb4ccb6021048702e34a482fb9c1d240d3852829529507c1c","sha512=71616981f5a15d6b2a47e18702083e52e81f6547076085b1489f676f50b0cc47c7c2c4fa19cb581e2878dc3d4f7133d0c50d8b51a8390be0e6e30318907d81d3"],"src":"https://github.com/hannesm/gmap/releases/download/0.3.0/gmap-0.3.0.tbz"}},"version":"0.3.0"},"graphql":{"authors":"Andreas Garnaes <andreas.garnaes@gmail.com>","bug-reports":"https://github.com/andreas/ocaml-graphql-server/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.9.0","prefix_relop":"geq"}],"val":"graphql_parser"},{"conditions":[{"arg":"1.6.0","prefix_relop":"geq"}],"val":"yojson"},{"conditions":[{"arg":"0.3.0","prefix_relop":"geq"}],"val":"rresult"},"seq",{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"\n`graphql` is a package for creating GraphQL servers. Current feature set includes:\n\n- Type-safe schema design\n- GraphQL parser in pure OCaml using [angstrom](https://github.com/inhabitedtype/angstrom) (April 2016 RFC draft)\n- Query execution\n- Introspection of schemas\n- Arguments for fields\n- Allows variables in queries\n- Subscriptions\n\nSupporting packages:\n\n- Use `graphql-lwt` for Lwt support.\n- Use `graphql-async` for Async support.\n- Use `graphql-cohttp` to run a GraphQL server with `cohttp`.","dev-repo":"git+https://github.com/andreas/ocaml-graphql-server.git","doc":"https://andreas.github.io/ocaml-graphql-server/","files-contents":{},"homepage":"https://github.com/andreas/ocaml-graphql-server","isLocal":false,"license":"MIT","maintainer":"Andreas Garnaes <andreas.garnaes@gmail.com>","name":"graphql","opam-version":"2.0","synopsis":"Build GraphQL schemas and execute queries against them","url":{"section":{"checksum":["sha256=bf8bf5b9e17e355ecbbd82158a769fe2b138e746753fd3a23008ada3afcd1c06","sha512=1d303d9ab67faecea8081f007b3696e36033aa65eba0854f50067b4d667d9a9ad185ad949371790a03509cb31bf6356b75c58f3066da9c35d82e620df5780185"],"src":"https://github.com/andreas/ocaml-graphql-server/releases/download/0.14.0/graphql-0.14.0.tbz"}},"version":"0.14.0","x-commit-hash":"79e01a09d08b0de3b3fff8195e19f7d8ab566498"},"graphql-lwt":{"authors":"Andreas Garnaes <andreas.garnaes@gmail.com>","bug-reports":"https://github.com/andreas/ocaml-graphql-server/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.13.0","prefix_relop":"geq"}],"val":"graphql"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.6.0","prefix_relop":"geq"}}],"val":"yojson"},"lwt"],"description":"\n`graphql-lwt` adds support for Lwt to `graphql`, so you can use Lwt in your GraphQL schema resolver functions.","dev-repo":"git+https://github.com/andreas/ocaml-graphql-server.git","doc":"https://andreas.github.io/ocaml-graphql-server/","files-contents":{},"homepage":"https://github.com/andreas/ocaml-graphql-server","isLocal":false,"license":"MIT","maintainer":"Andreas Garnaes <andreas.garnaes@gmail.com>","name":"graphql-lwt","opam-version":"2.0","synopsis":"Build GraphQL schemas with Lwt support","url":{"section":{"checksum":["sha256=bf8bf5b9e17e355ecbbd82158a769fe2b138e746753fd3a23008ada3afcd1c06","sha512=1d303d9ab67faecea8081f007b3696e36033aa65eba0854f50067b4d667d9a9ad185ad949371790a03509cb31bf6356b75c58f3066da9c35d82e620df5780185"],"src":"https://github.com/andreas/ocaml-graphql-server/releases/download/0.14.0/graphql-0.14.0.tbz"}},"version":"0.14.0","x-commit-hash":"79e01a09d08b0de3b3fff8195e19f7d8ab566498"},"graphql_parser":{"authors":"Andreas Garnaes <andreas.garnaes@gmail.com>","bug-reports":"https://github.com/andreas/ocaml-graphql-server/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"20180523","prefix_relop":"geq"}}],"val":"menhir"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.1","prefix_relop":"geq"}}],"val":"alcotest"},{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},{"conditions":[{"arg":"1.6.0","prefix_relop":"geq"}],"val":"re"}],"dev-repo":"git+https://github.com/andreas/ocaml-graphql-server.git","doc":"https://andreas.github.io/ocaml-graphql-server/","files-contents":{},"homepage":"https://github.com/andreas/ocaml-graphql-server","isLocal":false,"license":"MIT","maintainer":"Andreas Garnaes <andreas.garnaes@gmail.com>","name":"graphql_parser","opam-version":"2.0","synopsis":"Library for parsing GraphQL queries","url":{"section":{"checksum":["sha256=bf8bf5b9e17e355ecbbd82158a769fe2b138e746753fd3a23008ada3afcd1c06","sha512=1d303d9ab67faecea8081f007b3696e36033aa65eba0854f50067b4d667d9a9ad185ad949371790a03509cb31bf6356b75c58f3066da9c35d82e620df5780185"],"src":"https://github.com/andreas/ocaml-graphql-server/releases/download/0.14.0/graphql-0.14.0.tbz"}},"version":"0.14.0","x-commit-hash":"79e01a09d08b0de3b3fff8195e19f7d8ab566498"},"hmap":{"authors":["Daniel Bünzli <daniel.buenzl i@erratique.ch>"],"bug-reports":"http://github.com/dbuenzli/hmap/issues","build":[["ocaml","pkg/pkg.ml","build","--pinned","%{pinned}%"]],"depends":[{"conditions":[{"arg":"4.02.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"id":"build"}],"val":"topkg"}],"description":"\nHmap provides heterogeneous value maps for OCaml. These maps bind keys\nto values with arbitrary types. Keys witness the type of the value\nthey are bound to which allows to add and lookup bindings in a type\nsafe manner.\n\nHmap has no dependency and is distributed under the ISC license.","dev-repo":"git+http://erratique.ch/repos/hmap.git","doc":"http://erratique.ch/software/hmap/doc","files-contents":{},"homepage":"http://erratique.ch/software/hmap","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"hmap","opam-version":"2.0","synopsis":"Heterogeneous value maps for OCaml","tags":["data-structure","org:erratique"],"url":{"section":{"checksum":"md5=04169252265a11d852e1547445177196","src":"http://erratique.ch/software/hmap/releases/hmap-0.8.1.tbz"}},"version":"0.8.1"},"http":{"authors":["Anil Madhavapeddy","Stefano Zacchiroli","David Sheets","Thomas Gazagnaire","David Scott","Rudi Grinberg","Andy Ray","Anurag Soni"],"available":{"lhs":{"id":"opam-version"},"relop":"geq","rhs":"2.1.0"},"bug-reports":"https://github.com/mirage/ocaml-cohttp/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@http/runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"3.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-test"}],"val":"ppx_expect"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"base_quickcheck"},{"conditions":[{"id":"with-test"}],"val":"ppx_assert"},{"conditions":[{"id":"with-test"}],"val":"ppx_sexp_conv"},{"conditions":[{"id":"with-test"}],"val":"ppx_compare"},{"conditions":[{"id":"with-test"}],"val":"ppx_here"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.2","prefix_relop":"geq"}}],"val":"crowbar"},{"conditions":[{"id":"with-test"}],"val":"sexplib0"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nThis package contains essential type definitions used in Cohttp. It is designed\nto have no dependencies and make it easy for other packages to easily\ninteroperate with Cohttp.","dev-repo":"git+https://github.com/mirage/ocaml-cohttp.git","doc":"https://mirage.github.io/ocaml-cohttp/","files-contents":{},"flags":[{"id":"avoid-version"}],"homepage":"https://github.com/mirage/ocaml-cohttp","isLocal":false,"license":"ISC","maintainer":["Anil Madhavapeddy <anil@recoil.org>"],"name":"http","opam-version":"2.0","synopsis":"Type definitions of HTTP essentials","url":{"section":{"checksum":["sha256=2f00d14832c1c13427c12007e5b45a8f121e06e46d556a76904359ab26c0cff6","sha512=342034580418d55e7b9657c09cf187c415e562fc041e8f5eaa489cfae08f60b98afcddbc77632b479755cdfb2d30b5653ed5250b5b7dbde01f0be93f4e828bcc"],"src":"https://github.com/mirage/ocaml-cohttp/releases/download/v6.0.0_alpha2/cohttp-6.0.0.alpha2.tbz"}},"version":"6.0.0~alpha2","x-commit-hash":"bc9c78549a32d49be5fb51589331da51e86de269"},"ipaddr":{"authors":["David Sheets","Anil Madhavapeddy","Hugo Heuzard"],"bug-reports":"https://github.com/mirage/ocaml-ipaddr/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.9.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"macaddr"},{"conditions":[{"arg":"0.3.0","prefix_relop":"geq"}],"val":"domain-name"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.9.0","prefix_relop":"geq"}}],"val":"ppx_sexp_conv"}],"description":"\nFeatures:\n * Depends only on sexplib (conditionalization under consideration)\n * ounit2-based tests\n * IPv4 and IPv6 support\n * IPv4 and IPv6 CIDR prefix support\n * IPv4 and IPv6 [CIDR-scoped address](http://tools.ietf.org/html/rfc4291#section-2.3) support\n * `Ipaddr.V4` and `Ipaddr.V4.Prefix` modules are `Map.OrderedType`\n * `Ipaddr.V6` and `Ipaddr.V6.Prefix` modules are `Map.OrderedType`\n * `Ipaddr` and `Ipaddr.Prefix` modules are `Map.OrderedType`\n * `Ipaddr_unix` in findlib subpackage `ipaddr.unix` provides compatibility with the standard library `Unix` module\n * `Ipaddr_top` in findlib subpackage `ipaddr.top` provides top-level pretty printers (requires compiler-libs default since OCaml 4.0)\n * IP address scope classification\n * IPv4-mapped addresses in IPv6 (::ffff:0:0/96) are an embedding of IPv4\n * MAC-48 (Ethernet) address support\n * `Macaddr` is a `Map.OrderedType`\n * All types have sexplib serializers/deserializers\n","dev-repo":"git+https://github.com/mirage/ocaml-ipaddr.git","doc":"https://mirage.github.io/ocaml-ipaddr/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-ipaddr","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"ipaddr","opam-version":"2.0","synopsis":"A library for manipulation of IP (and MAC) address representations","tags":["org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=62890b316e035792ad29af1ad971456d10defd525b74b53db1b67fa42375c178","sha512=d9742648e3e4fe3d0bc7a5b08e62d97dab5d52b6421712c0415b345ddeb63a2a5fbb61e3083e90ae8cf05009673975e2e2ece5e15bce256ccd34cbe78d810c83"],"src":"https://github.com/mirage/ocaml-ipaddr/releases/download/v5.5.0/ipaddr-5.5.0.tbz"}},"version":"5.5.0","x-commit-hash":"234c6009a221e23a7dd4883756e6b2cc0d7c663b"},"ipaddr-sexp":{"authors":["David Sheets","Anil Madhavapeddy","Hugo Heuzard"],"bug-reports":"https://github.com/mirage/ocaml-ipaddr/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.9.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"ipaddr"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":{"id":"version"},"prefix_relop":"eq"}}],"val":"ipaddr-cstruct"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"arg":"v0.9.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"sexplib0"],"description":"\nSexp convertions for ipaddr\n","dev-repo":"git+https://github.com/mirage/ocaml-ipaddr.git","doc":"https://mirage.github.io/ocaml-ipaddr/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-ipaddr","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"ipaddr-sexp","opam-version":"2.0","synopsis":"A library for manipulation of IP address representations using sexp","tags":["org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=62890b316e035792ad29af1ad971456d10defd525b74b53db1b67fa42375c178","sha512=d9742648e3e4fe3d0bc7a5b08e62d97dab5d52b6421712c0415b345ddeb63a2a5fbb61e3083e90ae8cf05009673975e2e2ece5e15bce256ccd34cbe78d810c83"],"src":"https://github.com/mirage/ocaml-ipaddr/releases/download/v5.5.0/ipaddr-5.5.0.tbz"}},"version":"5.5.0","x-commit-hash":"234c6009a221e23a7dd4883756e6b2cc0d7c663b"},"jane-street-headers":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/jane-street-headers/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nC header files shared between the various Jane Street packages\n","dev-repo":"git+https://github.com/janestreet/jane-street-headers.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/jane-street-headers/index.html","files-contents":{},"homepage":"https://github.com/janestreet/jane-street-headers","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"jane-street-headers","opam-version":"2.0","synopsis":"Jane Street C header files","url":{"section":{"checksum":"sha256=876d409feeb495487b10010fb601c64829d2aa15f1b156b704ec141337d360ea","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/jane-street-headers-v0.16.0.tar.gz"}},"version":"v0.16.0"},"jst-config":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/jst-config/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_assert"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},"dune-configurator"],"description":"\nDefines compile-time constants used in Jane Street libraries such as Base, Core, and\nAsync.\n\nThis package has an unstable interface; it is intended only to share configuration between\ndifferent packages from Jane Street. Future updates may not be backward-compatible, and we\ndo not recommend using this package directly.\n","dev-repo":"git+https://github.com/janestreet/jst-config.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/jst-config/index.html","files-contents":{},"homepage":"https://github.com/janestreet/jst-config","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"jst-config","opam-version":"2.0","synopsis":"Compile-time configuration for Jane Street libraries","url":{"section":{"checksum":"sha256=faead56d8582868cdc099ad54f9bae059cc48710b724600cc64013e73c14d95b","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/jst-config-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ke":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/mirage/ke/issues","build":["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"bigstringaf"},{"conditions":[{"id":"with-test"}],"val":"bechamel"},{"conditions":[{"id":"with-test"}],"val":"bechamel-notty"},{"conditions":[{"id":"with-test"}],"val":"bechamel-perf"},{"conditions":[{"id":"with-test"}],"val":"ocplib-json-typed"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.15","prefix_relop":"geq"}}],"val":"core_bench"},{"conditions":[{"id":"with-test"}],"val":"lwt"},{"conditions":[{"id":"with-test"}],"val":"crowbar"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"id":"with-test"}],"val":"jsonm"},{"conditions":[{"id":"with-test"}],"val":"psq"},{"conditions":[{"lhs":{"arg":"1.1.0","prefix_relop":"geq"},"logop":"and","rhs":{"id":"with-test"}}],"val":"cmdliner"}],"description":"Queue implementation in OCaml (functional and imperative queue)","dev-repo":"git+https://github.com/mirage/ke.git","doc":"https://mirage.github.io/ke/","files-contents":{},"homepage":"https://github.com/mirage/ke","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"ke","opam-version":"2.0","run-test":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}],"synopsis":"Queue implementation","url":{"section":{"checksum":["sha256=61217207e2200b04b17759736610ff9208269a647f854cb5ae72cdac0d672305","sha512=be277780a7a6c9109068b6c8d54fa88c35180802ff86951516a32a6b7c0335fd6584753d1c670e02632b3956c09ae31bfec70e3dd5ea94697e9e032ba3b9248b"],"src":"https://github.com/mirage/ke/releases/download/v0.6/ke-0.6.tbz"}},"version":"0.6","x-commit-hash":"7678aee5921580378f543a11101b2b0118f2cf6c"},"logs":{"authors":["The logs programmers"],"bug-reports":"https://github.com/dbuenzli/logs/issues","build":[["ocaml","pkg/pkg.ml","build","--pinned","%{pinned}%","--with-js_of_ocaml","%{js_of_ocaml:installed}%","--with-fmt","%{fmt:installed}%","--with-cmdliner","%{cmdliner:installed}%","--with-lwt","%{lwt:installed}%","--with-base-threads","%{base-threads:installed}%"]],"conflicts":[{"conditions":[{"arg":"0.9.8","prefix_relop":"lt"}],"val":"cmdliner"},{"conditions":[{"arg":"3.3.0","prefix_relop":"lt"}],"val":"js_of_ocaml"}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"id":"build"}],"val":"topkg"},{"conditions":[{"id":"with-test"}],"val":"mtime"}],"depopts":["js_of_ocaml","fmt","cmdliner","lwt","base-threads"],"description":"\nLogs provides a logging infrastructure for OCaml. Logging is performed\non sources whose reporting level can be set independently. Log message\nreport is decoupled from logging and is handled by a reporter.\n\nA few optional log reporters are distributed with the base library and\nthe API easily allows to implement your own.\n\n`Logs` has no dependencies. The optional `Logs_fmt` reporter on OCaml\nformatters depends on [Fmt][fmt]. The optional `Logs_browser`\nreporter that reports to the web browser console depends on\n[js_of_ocaml][jsoo]. The optional `Logs_cli` library that provides\ncommand line support for controlling Logs depends on\n[`Cmdliner`][cmdliner]. The optional `Logs_lwt` library that provides\nLwt logging functions depends on [`Lwt`][lwt]\n\nLogs and its reporters are distributed under the ISC license.\n\n[fmt]: http://erratique.ch/software/fmt\n[jsoo]: http://ocsigen.org/js_of_ocaml/\n[cmdliner]: http://erratique.ch/software/cmdliner\n[lwt]: http://ocsigen.org/lwt/\n","dev-repo":"git+https://erratique.ch/repos/logs.git","doc":"https://erratique.ch/software/logs/doc","files-contents":{},"homepage":"https://erratique.ch/software/logs","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"logs","opam-version":"2.0","synopsis":"Logging infrastructure for OCaml","tags":["log","system","org:erratique"],"url":{"section":{"archive":"https://erratique.ch/software/logs/releases/logs-0.7.0.tbz","checksum":"2bf021ca13331775e33cf34ab60246f7"}},"version":"0.7.0"},"lwt":{"authors":["Jérôme Vouillon","Jérémie Dimino"],"bug-reports":"https://github.com/ocsigen/lwt/issues","build":[["dune","exec","-p",{"id":"name"},"src/unix/config/discover.exe","--","--save","--use-libev","%{conf-libev:installed}%"],["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.1.0","prefix_relop":"geq"}}],"val":"cppo"},{"conditions":[{"arg":"1.8.0","prefix_relop":"geq"}],"val":"dune"},"dune-configurator",{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},"ocplib-endian",{"conditions":[{"lhs":{"id":"dev"},"logop":"and","rhs":{"arg":"1.7.3-1","prefix_relop":"geq"}}],"val":"ocamlfind"}],"depopts":["base-threads","base-unix","conf-libev"],"description":"A promise is a value that may become determined in the future.\n\nLwt provides typed, composable promises. Promises that are resolved by I/O are\nresolved by Lwt in parallel.\n\nMeanwhile, OCaml code, including code creating and waiting on promises, runs in\na single thread by default. This reduces the need for locks or other\nsynchronization primitives. Code can be run in parallel on an opt-in basis.","dev-repo":"git+https://github.com/ocsigen/lwt.git","doc":"https://ocsigen.org/lwt","files-contents":{},"homepage":"https://github.com/ocsigen/lwt","isLocal":false,"license":"MIT","maintainer":["Raphaël Proust <code@bnwr.net>","Anton Bachin <antonbachin@yahoo.com>"],"name":"lwt","opam-version":"2.0","synopsis":"Promises and event-driven I/O","url":{"section":{"checksum":["md5=737039d29d45b2d2b35db6931c8d75c6","sha512=42e629920783428673b99c9d7a639237c9e6b35079b5d907bc67e7ea506acf9edadc48cec580bdcfd2410ed9412bf5e6bcc8b09de2fa7d35ce1490973d05ddd1"],"src":"https://github.com/ocsigen/lwt/archive/refs/tags/5.7.0.tar.gz"}},"version":"5.7.0"},"lwt_ppx":{"authors":["Gabriel Radanne"],"bug-reports":"https://github.com/ocsigen/lwt/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"1.8.0","prefix_relop":"geq"}],"val":"dune"},"lwt",{"conditions":[{"arg":"4.08","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"0.16.0","prefix_relop":"geq"}],"val":"ppxlib"}],"dev-repo":"git+https://github.com/ocsigen/lwt.git","doc":"https://ocsigen.org/lwt/dev/api/Ppx_lwt","files-contents":{},"homepage":"https://github.com/ocsigen/lwt","isLocal":false,"license":"MIT","maintainer":["Anton Bachin <antonbachin@yahoo.com>"],"name":"lwt_ppx","opam-version":"2.0","synopsis":"PPX syntax for Lwt, providing something similar to async/await from JavaScript","url":{"section":{"checksum":["md5=e63979ee40a80d5b9e9e5545f33323b4","sha512=d616389bc9e0da11f25843ab7541ac2d40c9543700a89455f14115b339bbe58cef2b8acf0ae97fd54e15a4cb93149cfe1ebfda301aa93933045f76b7d9344160"],"src":"https://github.com/ocsigen/lwt/archive/5.6.0.tar.gz"}},"version":"2.1.0"},"lwt_ssl":{"authors":["Jérôme Vouillon","Jérémie Dimino"],"bug-reports":"https://github.com/ocsigen/lwt_ssl/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":["base-unix","dune",{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"lwt"},"ocaml",{"conditions":[{"arg":"0.5.13","prefix_relop":"geq"}],"val":"ssl"}],"dev-repo":"git+https://github.com/ocsigen/lwt_ssl.git","doc":"https://github.com/ocsigen/lwt_ssl/blob/master/src/lwt_ssl.mli","files-contents":{},"homepage":"https://github.com/ocsigen/lwt_ssl","isLocal":false,"license":"LGPL with OpenSSL linking exception","maintainer":"Anton Bachin <antonbachin@yahoo.com>","name":"lwt_ssl","opam-version":"2.0","synopsis":"OpenSSL binding with concurrent I/O","url":{"section":{"checksum":["sha256=b3020ad27aecf377e1c3f2740a08b36dcbba991f843066511357410548889a77","sha512=cf2ef7d4db26e40c044e743ce85849a10eb57c916cbd7d6291bf4458291689098293bfb4cd7f1023f3ae8bc8e9a68cb2c7470669501a9b44695659405a75aa00"],"src":"https://github.com/ocsigen/lwt_ssl/releases/download/1.2.0/lwt_ssl-1.2.0.tbz"}},"version":"1.2.0","x-commit-hash":"d9ea0ab93da68f0d13ed710cc16f80983923f9ba"},"macaddr":{"authors":["David Sheets","Anil Madhavapeddy","Hugo Heuzard"],"bug-reports":"https://github.com/mirage/ocaml-ipaddr/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"3.0.0","prefix_relop":"lt"}],"val":"ipaddr"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.9.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.9.0","prefix_relop":"geq"}}],"val":"ppx_sexp_conv"}],"description":"\nA library for manipulation of MAC address representations.\n\nFeatures:\n\n * ounit2-based tests\n * MAC-48 (Ethernet) address support\n * `Macaddr` is a `Map.OrderedType`\n * All types have sexplib serializers/deserializers optionally via the `Macaddr_sexp` library.\n ","dev-repo":"git+https://github.com/mirage/ocaml-ipaddr.git","doc":"https://mirage.github.io/ocaml-ipaddr/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-ipaddr","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"macaddr","opam-version":"2.0","synopsis":"A library for manipulation of MAC address representations","tags":["org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=62890b316e035792ad29af1ad971456d10defd525b74b53db1b67fa42375c178","sha512=d9742648e3e4fe3d0bc7a5b08e62d97dab5d52b6421712c0415b345ddeb63a2a5fbb61e3083e90ae8cf05009673975e2e2ece5e15bce256ccd34cbe78d810c83"],"src":"https://github.com/mirage/ocaml-ipaddr/releases/download/v5.5.0/ipaddr-5.5.0.tbz"}},"version":"5.5.0","x-commit-hash":"234c6009a221e23a7dd4883756e6b2cc0d7c663b"},"magic-mime":{"authors":["Anil Madhavapeddy","Maxence Guesdon"],"bug-reports":"https://github.com/mirage/ocaml-magic-mime/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},"dune"],"description":"\nThis library contains a database of MIME types that maps filename extensions\ninto MIME types suitable for use in many Internet protocols such as HTTP or\ne-mail. It is generated from the `mime.types` file found in Unix systems, but\nhas no dependency on a filesystem since it includes the contents of the\ndatabase as an ML datastructure.\n\nFor example, here's how to lookup MIME types in the [utop] REPL:\n\n #require \"magic-mime\";;\n Magic_mime.lookup \"/foo/bar.txt\";;\n - : bytes = \"text/plain\"\n Magic_mime.lookup \"bar.css\";;\n - : bytes = \"text/css\"\n","dev-repo":"git+https://github.com/mirage/ocaml-magic-mime.git","doc":"https://mirage.github.io/ocaml-magic-mime/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-magic-mime","isLocal":false,"license":"ISC","maintainer":"Anil Madhavapeddy <anil@recoil.org>","name":"magic-mime","opam-version":"2.0","synopsis":"Map filenames to common MIME types","url":{"section":{"checksum":["sha256=e0234d03625dba1efac58e57e387672d75a5e9a621ff49acfe0f609c00f13b08","sha512=607f7469caa2e800a92e3c5248125108fad5e0513f4230a37ed774c86112eacdae0ee533c5c78ec2752e939e83e2201dd4ee02cbbff92ae32e25683710d7b365"],"src":"https://github.com/mirage/ocaml-magic-mime/releases/download/v1.3.1/magic-mime-1.3.1.tbz"}},"version":"1.3.1","x-commit-hash":"605338f0e3684425d99d853c15d5ea9a1478b5ee"},"menhir":{"authors":["François Pottier <francois.pottier@inria.fr>","Yann Régis-Gianas <yrg@pps.univ-paris-diderot.fr>"],"bug-reports":"https://gitlab.inria.fr/fpottier/menhir/-/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.8.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"menhirLib"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"menhirSdk"}],"dev-repo":"git+https://gitlab.inria.fr/fpottier/menhir.git","files-contents":{},"homepage":"http://gitlab.inria.fr/fpottier/menhir","isLocal":false,"license":"GPL-2.0-only","maintainer":"francois.pottier@inria.fr","name":"menhir","opam-version":"2.0","synopsis":"An LR(1) parser generator","url":{"section":{"checksum":["md5=8ff26b1e3685c472b7b3aba2fe938a43","sha512=334b9dcb1283a28b8547082a89536b1d439ff588290b8eaecdf4802c5f74dbc8d16ad6fc6c0820036183518d83e2cc273a75787a8b41137424c8e7ee82e2b50a"],"src":"https://gitlab.inria.fr/fpottier/menhir/-/archive/20230608/archive.tar.gz"}},"version":"20230608"},"menhirLib":{"authors":["François Pottier <francois.pottier@inria.fr>","Yann Régis-Gianas <yrg@pps.univ-paris-diderot.fr>"],"bug-reports":"https://gitlab.inria.fr/fpottier/menhir/-/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"conflicts":[{"conditions":[{"arg":{"id":"version"},"prefix_relop":"neq"}],"val":"menhir"}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.8.0","prefix_relop":"geq"}],"val":"dune"}],"dev-repo":"git+https://gitlab.inria.fr/fpottier/menhir.git","files-contents":{},"homepage":"http://gitlab.inria.fr/fpottier/menhir","isLocal":false,"license":"LGPL-2.0-only with OCaml-LGPL-linking-exception","maintainer":"francois.pottier@inria.fr","name":"menhirLib","opam-version":"2.0","synopsis":"Runtime support library for parsers generated by Menhir","url":{"section":{"checksum":["md5=8ff26b1e3685c472b7b3aba2fe938a43","sha512=334b9dcb1283a28b8547082a89536b1d439ff588290b8eaecdf4802c5f74dbc8d16ad6fc6c0820036183518d83e2cc273a75787a8b41137424c8e7ee82e2b50a"],"src":"https://gitlab.inria.fr/fpottier/menhir/-/archive/20230608/archive.tar.gz"}},"version":"20230608"},"menhirSdk":{"authors":["François Pottier <francois.pottier@inria.fr>","Yann Régis-Gianas <yrg@pps.univ-paris-diderot.fr>"],"bug-reports":"https://gitlab.inria.fr/fpottier/menhir/-/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"conflicts":[{"conditions":[{"arg":{"id":"version"},"prefix_relop":"neq"}],"val":"menhir"}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.8.0","prefix_relop":"geq"}],"val":"dune"}],"dev-repo":"git+https://gitlab.inria.fr/fpottier/menhir.git","files-contents":{},"homepage":"http://gitlab.inria.fr/fpottier/menhir","isLocal":false,"license":"LGPL-2.0-only with OCaml-LGPL-linking-exception","maintainer":"francois.pottier@inria.fr","name":"menhirSdk","opam-version":"2.0","synopsis":"Compile-time library for auxiliary tools related to Menhir","url":{"section":{"checksum":["md5=8ff26b1e3685c472b7b3aba2fe938a43","sha512=334b9dcb1283a28b8547082a89536b1d439ff588290b8eaecdf4802c5f74dbc8d16ad6fc6c0820036183518d83e2cc273a75787a8b41137424c8e7ee82e2b50a"],"src":"https://gitlab.inria.fr/fpottier/menhir/-/archive/20230608/archive.tar.gz"}},"version":"20230608"},"mirage-clock":{"authors":["Anil Madhavapeddy","Daniel C. Bünzli","Matthew Gray"],"bug-reports":"https://github.com/mirage/mirage-clock/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.8","prefix_relop":"geq"}],"val":"dune"}],"description":"\nThis library implements portable support for an operating system timesource\nthat is compatible with the [MirageOS](https://mirage.io) library interfaces\nfound in: <https://github.com/mirage/mirage>\n\nIt implements an `MCLOCK` module that represents a monotonic timesource\nsince an arbitrary point, and `PCLOCK` which counts time since the Unix\nepoch.\n","dev-repo":"git+https://github.com/mirage/mirage-clock.git","doc":"https://mirage.github.io/mirage-clock/","files-contents":{},"homepage":"https://github.com/mirage/mirage-clock","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"mirage-clock","opam-version":"2.0","synopsis":"Libraries and module types for portable clocks","tags":"org:mirage","url":{"section":{"checksum":["sha256=fa17d15d5be23c79ba741f5f7cb88ed7112de16a4410cea81c71b98086889847","sha512=05a359dc8400d4ca200ff255dbd030acd33d2c4acb5020838f772c02cdb5f243f3dbafbc43a8cd51e6b5923a140f84c9e7ea25b2c0fa277bb68b996190d36e3b"],"src":"https://github.com/mirage/mirage-clock/releases/download/v4.2.0/mirage-clock-4.2.0.tbz"}},"version":"4.2.0","x-commit-hash":"f457572bfedb9586c8bf9eaa9ece7e53677856e3"},"mirage-crypto":{"authors":["David Kaloper <dk505@cam.ac.uk>","Hannes Mehnert <hannes@mehnert.org>"],"bug-reports":"https://github.com/mirage/mirage-crypto/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":["ocaml-freestanding"],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune-configurator"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},{"conditions":[{"arg":"0.8","prefix_relop":"geq"}],"val":"eqaf"}],"description":"\nMirage-crypto provides symmetric ciphers (DES, AES, RC4, ChaCha20/Poly1305), and\nhashes (MD5, SHA-1, SHA-2).\n","dev-repo":"git+https://github.com/mirage/mirage-crypto.git","doc":"https://mirage.github.io/mirage-crypto/doc","files-contents":{},"homepage":"https://github.com/mirage/mirage-crypto","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"mirage-crypto","opam-version":"2.0","synopsis":"Simple symmetric cryptography for the modern age","url":{"section":{"checksum":["sha256=d6b97cb7f0dc344a602513cc03137c1e7f0ae105d0721614626cf4f231edf764","sha512=7ab8824730d09bfb4c82a290860e96c8a722456084806741c773ab8d30c983d2061a3f79484debf5fa9bd1c75a0738bd8913b0539743e61245ad172844572b9e"],"src":"https://github.com/mirage/mirage-crypto/releases/download/v0.11.2/mirage-crypto-0.11.2.tbz"}},"version":"0.11.2","x-commit-hash":"586874a3d51fbe149e7ff17658d9532f3cf5d4d3"},"mirage-crypto-ec":{"authors":["Hannes Mehnert <hannes@mehnert.org>","Nathan Rebours <nathan.p.rebours@gmail.com>","Clément Pascutto <clement@tarides.com>","Etienne Millon <me@emillon.org>","Andres Erbsen <andreser@mit.edu>","Google Inc.","Jade Philipoom <jadep@mit.edu> <jade.philipoom@gmail.com>","Massachusetts Institute of Technology","Zoe Paraskevopoulou <zoe.paraskevopoulou@gmail.com>"],"bug-reports":"https://github.com/mirage/mirage-crypto/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":["ocaml-freestanding"],"depends":[{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},"dune-configurator",{"conditions":[{"arg":"0.7","prefix_relop":"geq"}],"val":"eqaf"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto-rng"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":{"id":"version"},"prefix_relop":"eq"}}],"val":"mirage-crypto-pk"},{"conditions":[{"id":"with-test"}],"val":"hex"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.1","prefix_relop":"geq"}}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.2.5","prefix_relop":"geq"}}],"val":"asn1-combinators"},{"conditions":[{"id":"with-test"}],"val":"ppx_deriving_yojson"},{"conditions":[{"id":"with-test"}],"val":"ppx_deriving"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.6.0","prefix_relop":"geq"}}],"val":"yojson"}],"description":"\nAn implementation of key exchange (ECDH) and digital signature (ECDSA/EdDSA)\nalgorithms using code from Fiat (<https://github.com/mit-plv/fiat-crypto>).\n\nThe curves P224 (SECP224R1), P256 (SECP256R1), P384 (SECP384R1),\nP521 (SECP521R1), and 25519 (X25519, Ed25519) are implemented by this package.\n","dev-repo":"git+https://github.com/mirage/mirage-crypto.git","doc":"https://mirage.github.io/mirage-crypto/doc","files-contents":{},"homepage":"https://github.com/mirage/mirage-crypto","isLocal":false,"license":"MIT","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"mirage-crypto-ec","opam-version":"2.0","synopsis":"Elliptic Curve Cryptography with primitives taken from Fiat","tags":["org:mirage"],"url":{"section":{"checksum":["sha256=d6b97cb7f0dc344a602513cc03137c1e7f0ae105d0721614626cf4f231edf764","sha512=7ab8824730d09bfb4c82a290860e96c8a722456084806741c773ab8d30c983d2061a3f79484debf5fa9bd1c75a0738bd8913b0539743e61245ad172844572b9e"],"src":"https://github.com/mirage/mirage-crypto/releases/download/v0.11.2/mirage-crypto-0.11.2.tbz"}},"version":"0.11.2","x-commit-hash":"586874a3d51fbe149e7ff17658d9532f3cf5d4d3"},"mirage-crypto-pk":{"authors":["David Kaloper <dk505@cam.ac.uk>","Hannes Mehnert <hannes@mehnert.org>"],"bug-reports":"https://github.com/mirage/mirage-crypto/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":["ocaml-freestanding"],"depends":[{"conditions":[{"id":"build"}],"val":"conf-gmp-powm-sec"},{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.1.3","prefix_relop":"geq"}}],"val":"randomconv"},{"conditions":[{"arg":"6.00","prefix_relop":"geq"}],"val":"cstruct"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto-rng"},"sexplib0",{"conditions":[{"arg":"1.4","prefix_relop":"geq"}],"val":"zarith"},{"conditions":[{"arg":"0.8","prefix_relop":"geq"}],"val":"eqaf"}],"description":"\nMirage-crypto-pk provides public-key cryptography (RSA, DSA, DH).\n","dev-repo":"git+https://github.com/mirage/mirage-crypto.git","doc":"https://mirage.github.io/mirage-crypto/doc","files-contents":{},"homepage":"https://github.com/mirage/mirage-crypto","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"mirage-crypto-pk","opam-version":"2.0","synopsis":"Simple public-key cryptography for the modern age","url":{"section":{"checksum":["sha256=d6b97cb7f0dc344a602513cc03137c1e7f0ae105d0721614626cf4f231edf764","sha512=7ab8824730d09bfb4c82a290860e96c8a722456084806741c773ab8d30c983d2061a3f79484debf5fa9bd1c75a0738bd8913b0539743e61245ad172844572b9e"],"src":"https://github.com/mirage/mirage-crypto/releases/download/v0.11.2/mirage-crypto-0.11.2.tbz"}},"version":"0.11.2","x-commit-hash":"586874a3d51fbe149e7ff17658d9532f3cf5d4d3"},"mirage-crypto-rng":{"authors":["David Kaloper <dk505@cam.ac.uk>","Hannes Mehnert <hannes@mehnert.org>"],"bug-reports":"https://github.com/mirage/mirage-crypto/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"3.8.0","prefix_relop":"lt"}],"val":"mirage-runtime"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune-configurator"},"duration",{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},"logs",{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto"},{"conditions":[{"id":"with-test"}],"val":"ounit2"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.1.3","prefix_relop":"geq"}}],"val":"randomconv"}],"description":"\nMirage-crypto-rng provides a random number generator interface, and\nimplementations: Fortuna, HMAC-DRBG, getrandom/getentropy based (in the unix\nsublibrary)\n","dev-repo":"git+https://github.com/mirage/mirage-crypto.git","doc":"https://mirage.github.io/mirage-crypto/doc","files-contents":{},"homepage":"https://github.com/mirage/mirage-crypto","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"mirage-crypto-rng","opam-version":"2.0","synopsis":"A cryptographically secure PRNG","url":{"section":{"checksum":["sha256=d6b97cb7f0dc344a602513cc03137c1e7f0ae105d0721614626cf4f231edf764","sha512=7ab8824730d09bfb4c82a290860e96c8a722456084806741c773ab8d30c983d2061a3f79484debf5fa9bd1c75a0738bd8913b0539743e61245ad172844572b9e"],"src":"https://github.com/mirage/mirage-crypto/releases/download/v0.11.2/mirage-crypto-0.11.2.tbz"}},"version":"0.11.2","x-commit-hash":"586874a3d51fbe149e7ff17658d9532f3cf5d4d3"},"mirage-crypto-rng-lwt":{"authors":["David Kaloper <dk505@cam.ac.uk>","Hannes Mehnert <hannes@mehnert.org>"],"bug-reports":"https://github.com/mirage/mirage-crypto/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},"duration","logs",{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto"},{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"mirage-crypto-rng"},{"conditions":[{"arg":"1.0.0","prefix_relop":"geq"}],"val":"mtime"},{"conditions":[{"arg":"4.0.0","prefix_relop":"geq"}],"val":"lwt"}],"description":"\nMirage-crypto-rng-lwt provides entropy collection code for the RNG using Lwt.\n","dev-repo":"git+https://github.com/mirage/mirage-crypto.git","doc":"https://mirage.github.io/mirage-crypto/doc","files-contents":{},"homepage":"https://github.com/mirage/mirage-crypto","isLocal":false,"license":"ISC","maintainer":"Hannes Mehnert <hannes@mehnert.org>","name":"mirage-crypto-rng-lwt","opam-version":"2.0","synopsis":"A cryptographically secure PRNG","url":{"section":{"checksum":["sha256=d6b97cb7f0dc344a602513cc03137c1e7f0ae105d0721614626cf4f231edf764","sha512=7ab8824730d09bfb4c82a290860e96c8a722456084806741c773ab8d30c983d2061a3f79484debf5fa9bd1c75a0738bd8913b0539743e61245ad172844572b9e"],"src":"https://github.com/mirage/mirage-crypto/releases/download/v0.11.2/mirage-crypto-0.11.2.tbz"}},"version":"0.11.2","x-commit-hash":"586874a3d51fbe149e7ff17658d9532f3cf5d4d3"},"mtime":{"authors":"The mtime programmers","bug-reports":"https://github.com/dbuenzli/mtime/issues","build":["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%"],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"0.9.0","prefix_relop":"neq"}}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"}],"description":"Mtime has platform independent support for monotonic wall-clock time\nin pure OCaml. This time increases monotonically and is not subject to\noperating system calendar time adjustments. The library has types to\nrepresent nanosecond precision timestamps and time spans.\n\nThe additional Mtime_clock library provide access to a system\nmonotonic clock.\n\nMtime has a no dependency. Mtime_clock depends on your system library\nor JavaScript runtime system. Mtime and its libraries are distributed\nunder the ISC license.\n\nHome page: <http://erratique.ch/software/mtime>","dev-repo":"git+https://erratique.ch/repos/mtime.git","doc":"https://erratique.ch/software/mtime/doc/","files-contents":{},"homepage":"https://erratique.ch/software/mtime","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"mtime","opam-version":"2.0","synopsis":"Monotonic wall-clock time for OCaml","tags":["time","monotonic","system","org:erratique"],"url":{"section":{"checksum":"sha512=2ebec45218901c08f73420aa3318c506f155b6c0df713e9856682e59d3246696821ea477ce3682af0bf4cafd0491b1d66904f8c0256e2cf831e93a0aea322f04","src":"https://erratique.ch/software/mtime/releases/mtime-2.0.0.tbz"}},"version":"2.0.0"},"multipart_form":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/dinosaure/multipart_form/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"1.5","prefix_relop":"lt"}],"val":"result"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.14.0","prefix_relop":"geq"}],"val":"angstrom"},{"conditions":[{"arg":"3.0.0","prefix_relop":"geq"}],"val":"base64"},{"conditions":[{"arg":"0.2","prefix_relop":"geq"}],"val":"unstrctrd"},"uutf",{"conditions":[{"arg":"0.4","prefix_relop":"geq"}],"val":"pecu"},"prettym","result",{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},"logs",{"conditions":[{"arg":"0.6","prefix_relop":"geq"}],"val":"ke"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"rosetta"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"arg":"0.9.0","prefix_relop":"geq"}],"val":"bigstringaf"}],"description":"Implementation of RFC7578 in OCaml\n\nReturning values from forms: multipart/form-data","dev-repo":"git+https://github.com/dinosaure/multipart_form.git","doc":"https://dinosaure.github.io/multipart_form/","files-contents":{},"homepage":"https://github.com/dinosaure/multipart_form","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"multipart_form","opam-version":"2.0","synopsis":"Multipart-form: RFC2183, RFC2388 & RFC7578","url":{"section":{"checksum":["sha256=a8a36c1c0e2873ba1b3bd32ccdfb8fb6766e06612e52e36b3077a6a296a88a64","sha512=f1e95b201e5474687e31bb132ca17ab9799d9957cbc91d0d7fdc160bbcfb2b6f6a77e37fba802c5a41339cb699987667e029672d58096ebfd06fd932b352bd46"],"src":"https://github.com/dinosaure/multipart_form/releases/download/v0.5.0/multipart_form-0.5.0.tbz"}},"version":"0.5.0","x-commit-hash":"f88dcd04dcea0c343914cd6fba199ac717d9175d"},"multipart_form-lwt":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/dinosaure/multipart_form/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},"angstrom","bigstringaf","ke","lwt",{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"multipart_form"},{"conditions":[{"id":"with-test"}],"val":"alcotest-lwt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"rosetta"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"id":"with-test"}],"val":"unstrctrd"},{"conditions":[{"id":"with-test"}],"val":"logs"}],"description":"Implementation of RFC7578 in OCaml\n\nReturning values from forms: multipart/form-data","dev-repo":"git+https://github.com/dinosaure/multipart_form.git","doc":"https://dinosaure.github.io/multipart_form/","files-contents":{},"homepage":"https://github.com/dinosaure/multipart_form","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"multipart_form-lwt","opam-version":"2.0","synopsis":"Multipart-form: RFC2183, RFC2388 & RFC7578","url":{"section":{"checksum":["sha256=a8a36c1c0e2873ba1b3bd32ccdfb8fb6766e06612e52e36b3077a6a296a88a64","sha512=f1e95b201e5474687e31bb132ca17ab9799d9957cbc91d0d7fdc160bbcfb2b6f6a77e37fba802c5a41339cb699987667e029672d58096ebfd06fd932b352bd46"],"src":"https://github.com/dinosaure/multipart_form/releases/download/v0.5.0/multipart_form-0.5.0.tbz"}},"version":"0.5.0","x-commit-hash":"f88dcd04dcea0c343914cd6fba199ac717d9175d"},"num":{"authors":["Valérie Ménissier-Morain","Pierre Weis","Xavier Leroy"],"bug-reports":"https://github.com/ocaml/num/issues","build":[[{"id":"make"},"PROFILE=release",{"conditions":[{"lhs":{"arg":{"id":"ocaml:preinstalled"},"pfxop":"not"},"logop":"and","rhs":{"lhs":{"id":"ocaml:version"},"relop":"lt","rhs":"5.0.0~~"}}],"val":"opam-legacy"},{"conditions":[{"lhs":{"id":"ocaml:preinstalled"},"logop":"or","rhs":{"lhs":{"id":"ocaml:version"},"relop":"geq","rhs":"5.0.0~~"}}],"val":"opam-modern"}],{"conditions":[{"id":"with-test"}],"val":[{"id":"make"},"test"]}],"conflicts":["base-num"],"depends":[{"conditions":[{"arg":"4.06.0","prefix_relop":"geq"}],"val":"ocaml"}],"dev-repo":"git+https://github.com/ocaml/num.git","files-contents":{},"homepage":"https://github.com/ocaml/num/","isLocal":false,"license":"LGPL-2.1-only WITH OCaml-LGPL-linking-exception","maintainer":"Xavier Leroy <xavier.leroy@inria.fr>","name":"num","opam-version":"2.0","synopsis":"The legacy Num library for arbitrary-precision integer and rational arithmetic","url":{"section":{"checksum":["md5=b1f9405dfe5f573ea187f122f789ae57","sha512=110dd01140c1c96f5f067aa824bb63f74a26411dcaa65aaf04cb6c44b116ca02aaab9505f431c66964388ce4a31d86da5928b4c0e5557800e834de80bed46495"],"src":"https://github.com/ocaml/num/archive/v1.5.tar.gz"}},"version":"1.5"},"ocaml":{"authors":["Xavier Leroy","Damien Doligez","Alain Frisch","Jacques Garrigue","Didier Rémy","Jérôme Vouillon"],"bug-reports":"https://github.com/ocaml/opam-repository/issues","build":["ocaml","%{ocaml-config:share}%/gen_ocaml_config.ml",{"id":"_:version"},{"id":"_:name"}],"build-env":[[{"lhs":{"id":"CAML_LD_LIBRARY_PATH"},"relop":"eq","rhs":""}],[{"lhs":{"id":"LSAN_OPTIONS"},"relop":"eq","rhs":"detect_leaks=0,exitcode=0"}],[{"lhs":{"id":"ASAN_OPTIONS"},"relop":"eq","rhs":"detect_leaks=0,exitcode=0"}]],"depends":[{"conditions":[{"arg":"3","prefix_relop":"geq"}],"val":"ocaml-config"},{"lhs":{"lhs":{"lhs":{"conditions":[{"lhs":{"arg":"5.1.1~","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"5.1.2~","prefix_relop":"lt"}}],"val":"ocaml-base-compiler"},"logop":"or","rhs":{"conditions":[{"lhs":{"arg":"5.1.1~","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"5.1.2~","prefix_relop":"lt"}}],"val":"ocaml-variants"}},"logop":"or","rhs":{"conditions":[{"lhs":{"arg":"5.1.1~","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"5.1.2~","prefix_relop":"lt"}}],"val":"ocaml-system"}},"logop":"or","rhs":{"conditions":[{"lhs":{"arg":"5.1.1~","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"5.1.2~","prefix_relop":"lt"}}],"val":"dkml-base-compiler"}}],"description":"\nThis package requires a matching implementation of OCaml,\nand polls it to initialise specific variables like `ocaml:native-dynlink`","files-contents":{},"flags":{"id":"conf"},"homepage":"https://ocaml.org","isLocal":false,"license":"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception","maintainer":"platform@lists.ocaml.org","name":"ocaml","opam-version":"2.0","setenv":[[{"lhs":{"id":"CAML_LD_LIBRARY_PATH"},"relop":"eq","rhs":"%{_:stubsdir}%"}],[{"env_update":"prepend","lhs":{"id":"CAML_LD_LIBRARY_PATH"},"rhs":"%{lib}%/stublibs"}],[{"lhs":{"id":"OCAML_TOPLEVEL_PATH"},"relop":"eq","rhs":"%{toplevel}%"}]],"synopsis":"The OCaml compiler (virtual package)","version":"5.1.1"},"ocaml-base-compiler":{"authors":"Xavier Leroy and many contributors","bug-reports":"https://github.com/ocaml/opam-repository/issues","build":[["./configure","--prefix=%{prefix}%","--docdir=%{doc}%/ocaml","-C",{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"openbsd"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"}}],"val":"CC=cc"},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"openbsd"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"}}],"val":"ASPP=cc -c"}],[{"id":"make"},"-j%{jobs}%"]],"conflict-class":"ocaml-core-compiler","depends":[{"conditions":[{"lhs":{"arg":"5.1.1","prefix_relop":"eq"},"logop":"and","rhs":{"id":"post"}}],"val":"ocaml"},{"conditions":[{"id":"post"}],"val":"base-unix"},{"conditions":[{"id":"post"}],"val":"base-bigarray"},{"conditions":[{"id":"post"}],"val":"base-threads"},{"conditions":[{"id":"post"}],"val":"base-domains"},{"conditions":[{"id":"post"}],"val":"base-nnp"},{"conditions":[{"id":"post"}],"val":"ocaml-options-vanilla"},{"conditions":[{"lhs":{"lhs":{"lhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"arm64"},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"x86_64"}},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"s390x"}},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"riscv64"}}],"val":"ocaml-option-bytecode-only"},{"conditions":[{"lhs":{"id":"opam-version"},"relop":"lt","rhs":"2.1.0"}],"val":"ocaml-beta"}],"dev-repo":"git+https://github.com/ocaml/ocaml#5.1","extra-files":["ocaml-base-compiler.install","md5=3e969b841df1f51ca448e6e6295cb451"],"files-contents":{"ocaml-base-compiler.install":"share_root: [\"config.cache\" {\"ocaml/config.cache\"}]\n"},"flags":[{"id":"compiler"},{"id":"avoid-version"}],"homepage":"https://ocaml.org","install":[{"id":"make"},"install"],"isLocal":false,"license":"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception","maintainer":"platform@lists.ocaml.org","name":"ocaml-base-compiler","opam-version":"2.0","post-messages":[{"conditions":[{"lhs":{"id":"failure"},"logop":"and","rhs":{"lhs":{"id":"jobs"},"relop":"gt","rhs":1}}],"val":"A failure in the middle of the build may be caused by build parallelism\n (enabled by default).\n Please file a bug report at https://github.com/ocaml/opam-repository/issues"},{"conditions":[{"lhs":{"lhs":{"id":"failure"},"logop":"and","rhs":{"lhs":{"id":"jobs"},"relop":"gt","rhs":1}},"logop":"and","rhs":{"lhs":{"id":"opam-version"},"relop":"geq","rhs":"2.0.5"}}],"val":"You can try installing again including --jobs=1\n to force a sequential build instead."}],"setenv":{"lhs":{"id":"CAML_LD_LIBRARY_PATH"},"relop":"eq","rhs":"%{lib}%/stublibs"},"synopsis":"First release candidate of OCaml 5.1.1","url":{"section":{"checksum":"sha256=abef810bbe0e8f10f56438d58f57e442e024bca724815c113f8c481ad518827b","src":"https://github.com/ocaml/ocaml/archive/5.1.1-rc1.tar.gz"}},"version":"5.1.1~rc1"},"ocaml-compiler-libs":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ocaml-compiler-libs/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.8","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.04.1","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nThis packages exposes the OCaml compiler libraries repackages under\nthe toplevel names Ocaml_common, Ocaml_bytecomp, Ocaml_optcomp, ...","dev-repo":"git+https://github.com/janestreet/ocaml-compiler-libs.git","files-contents":{},"homepage":"https://github.com/janestreet/ocaml-compiler-libs","isLocal":false,"license":"MIT","maintainer":["Jane Street developers"],"name":"ocaml-compiler-libs","opam-version":"2.0","synopsis":"OCaml compiler libraries repackaged","url":{"section":{"checksum":["sha256=4ec9c9ec35cc45c18c7a143761154ef1d7663036a29297f80381f47981a07760","sha512=978dba8dfa61f98fa24fda7a9c26c2e837081f37d1685fe636dc19cfc3278a940cf01a10293504b185c406706bc1008bc54313d50f023bcdea6d5ac6c0788b35"],"src":"https://github.com/janestreet/ocaml-compiler-libs/releases/download/v0.12.4/ocaml-compiler-libs-v0.12.4.tbz"}},"version":"v0.12.4","x-commit-hash":"8cd12f18bb7171c2b67d661868c4271fae528d93"},"ocaml-config":{"authors":["Louis Gesbert <louis.gesbert@ocamlpro.com>","David Allsopp <david.allsopp@metastack.com>"],"bug-reports":"https://github.com/ocaml/opam/issues","depends":[{"lhs":{"lhs":{"lhs":{"conditions":[{"lhs":{"arg":"5.0.0~","prefix_relop":"geq"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"}}],"val":"ocaml-base-compiler"},"logop":"or","rhs":{"conditions":[{"lhs":{"arg":"5.0.0~","prefix_relop":"geq"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"}}],"val":"ocaml-variants"}},"logop":"or","rhs":{"conditions":[{"lhs":{"arg":"5.0.0~","prefix_relop":"geq"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"win32"}}],"val":"ocaml-system"}},"logop":"or","rhs":{"conditions":[{"arg":"4.12.0~","prefix_relop":"geq"}],"val":"dkml-base-compiler"}}],"description":"\nThis package is used by the OCaml package to set-up its variables.","extra-files":[["gen_ocaml_config.ml.in","md5=c0a50fb1f6ffe7a48bf8600e83ae6d38"],["ocaml-config.install","md5=8e50c5e2517d3463b3aad649748cafd7"]],"files-contents":{"gen_ocaml_config.ml.in":"let () =\n let ocaml_version =\n let v = Sys.ocaml_version in\n let l = String.length v in\n let plus = try String.index v '+' with Not_found -> l in\n (* Introduced in 4.11.0; used from 4.12.0 *)\n let tilde = try String.index v '~' with Not_found -> l in\n String.sub v 0 (min (min plus tilde) l)\n in\n if ocaml_version <> Sys.argv.(1) then\n (Printf.eprintf\n \"OCaml version mismatch: %%s, expected %s\"\n ocaml_version Sys.argv.(1);\n exit 1)\n else\n let oc = open_out (Sys.argv.(2) ^ \".config\") in\n let exe = \".exe\" in\n let (ocaml, suffix) =\n let s = Sys.executable_name in\n if Filename.check_suffix s exe then\n (Filename.chop_suffix s exe, exe)\n else\n (s, \"\")\n in\n let ocamlc = ocaml^\"c\"^suffix in\n let libdir =\n if Sys.command (ocamlc^\" -where > where\") = 0 then\n (* Must be opened in text mode for Windows *)\n let ic = open_in \"where\" in\n let r = input_line ic in\n close_in ic; r\n else\n failwith \"Bad return from 'ocamlc -where'\"\n in\n let stubsdir =\n let ic = open_in (Filename.concat libdir \"ld.conf\") in\n let rec r acc = try r (input_line ic::acc) with End_of_file -> acc in\n let lines = List.rev (r []) in\n close_in ic;\n let sep = if Sys.os_type = \"Win32\" then \";\" else \":\" in\n String.concat sep lines\n in\n let has_native_dynlink =\n let check_dir libdir =\n Sys.file_exists (Filename.concat libdir \"dynlink.cmxa\")\n in\n List.exists check_dir [Filename.concat libdir \"dynlink\"; libdir]\n in\n let p fmt = Printf.fprintf oc (fmt ^^ \"\\n\") in\n p \"opam-version: \\\"2.0\\\"\";\n p \"variables {\";\n p \" native: %%b\"\n (Sys.file_exists (ocaml^\"opt\"^suffix));\n p \" native-tools: %%b\"\n (* The variable [ocamlc] already has a suffix on Windows\n (ex. '...\\bin\\ocamlc.exe') so we use [ocaml] to check *)\n (Sys.file_exists (ocaml^\"c.opt\"^suffix));\n p \" native-dynlink: %%b\"\n has_native_dynlink;\n p \" stubsdir: %%S\"\n stubsdir;\n p \" preinstalled: %{ocaml-system:installed}%\";\n p \" compiler: \\\"%{ocaml-system:installed?system:}%%{ocaml-base-compiler:version}%%{dkml-base-compiler:version}%%{ocaml-variants:version}%%{ocaml-option-32bit:installed?+32bit:}%%{ocaml-option-afl:installed?+afl:}%%{ocaml-option-bytecode-only:installed?+bytecode-only:}%%{ocaml-option-default-unsafe-string:installed?+default-unsafe-string:}%%{ocaml-option-fp:installed?+fp:}%%{ocaml-option-flambda:installed?+flambda:}%%{ocaml-option-musl:installed?+musl:}%%{ocaml-option-nnp:installed?+nnp:}%%{ocaml-option-no-flat-float-array:installed?+no-flat-float-array:}%%{ocaml-option-spacetime:installed?+spacetime:}%%{ocaml-option-static:installed?+static:}%\\\"\";\n p \"}\";\n close_out oc\n","ocaml-config.install":"share: [\"gen_ocaml_config.ml\"]\n"},"homepage":"https://opam.ocaml.org/","isLocal":false,"license":"ISC","maintainer":"platform@lists.ocaml.org","name":"ocaml-config","opam-version":"2.0","substs":"gen_ocaml_config.ml","synopsis":"OCaml Switch Configuration","version":"3"},"ocaml-options-vanilla":{"conflicts":["ocaml-option-32bit","ocaml-option-afl",{"conditions":[{"lhs":{"lhs":{"id":"arch"},"relop":"eq","rhs":"arm64"},"logop":"or","rhs":{"lhs":{"id":"arch"},"relop":"eq","rhs":"x86_64"}}],"val":"ocaml-option-bytecode-only"},"ocaml-option-default-unsafe-string","ocaml-option-flambda","ocaml-option-fp","ocaml-option-musl","ocaml-option-no-flat-float-array","ocaml-option-no-compression","ocaml-option-spacetime","ocaml-option-static","ocaml-option-nnp","ocaml-option-nnpchecker","ocaml-option-address-sanitizer","ocaml-option-leak-sanitizer","ocaml-option-tsan"],"depends":[{"lhs":{"lhs":{"conditions":[{"id":"post"}],"val":"ocaml-base-compiler"},"logop":"or","rhs":{"conditions":[{"id":"post"}],"val":"ocaml-system"}},"logop":"or","rhs":{"conditions":[{"lhs":{"id":"post"},"logop":"and","rhs":{"arg":"4.12.0~","prefix_relop":"geq"}}],"val":"ocaml-variants"}}],"files-contents":{},"flags":{"id":"compiler"},"isLocal":false,"maintainer":"platform@lists.ocaml.org","name":"ocaml-options-vanilla","opam-version":"2.0","synopsis":"Ensure that OCaml is compiled with no special options enabled","version":"1"},"ocaml-syntax-shims":{"authors":["Jérémie Dimino <jeremie@dimino.org>"],"bug-reports":"https://github.com/ocaml-ppx/ocaml-syntax-shims/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"}],"description":"\nThis packages backports new features of the language to older\ncompilers, such as let+.\n","dev-repo":"git+https://github.com/ocaml-ppx/ocaml-syntax-shims.git","doc":"https://ocaml-ppx.github.io/ocaml-syntax-shims/","files-contents":{},"homepage":"https://github.com/ocaml-ppx/ocaml-syntax-shims","isLocal":false,"license":"MIT","maintainer":["jeremie@dimino.org"],"name":"ocaml-syntax-shims","opam-version":"2.0","synopsis":"Backport new syntax to older OCaml versions","url":{"section":{"checksum":["sha256=89b2e193e90a0c168b6ec5ddf6fef09033681bdcb64e11913c97440a2722e8c8","sha512=75c4c6b0bfa1267a8a49a82ba494d08cf0823fc8350863d6d3d4971528cb09e5a2a29e2981d04c75e76ad0f49360b05a432c9efeff9a4fbc1ec6b28960399852"],"src":"https://github.com/ocaml-ppx/ocaml-syntax-shims/releases/download/1.0.0/ocaml-syntax-shims-1.0.0.tbz"}},"version":"1.0.0"},"ocamlbuild":{"authors":["Nicolas Pouillard","Berke Durak"],"available":{"lhs":{"id":"os"},"relop":"neq","rhs":"win32"},"bug-reports":"https://github.com/ocaml/ocamlbuild/issues","build":[[{"id":"make"},"-f","configure.make","all","OCAMLBUILD_PREFIX=%{prefix}%","OCAMLBUILD_BINDIR=%{bin}%","OCAMLBUILD_LIBDIR=%{lib}%","OCAMLBUILD_MANDIR=%{man}%","OCAML_NATIVE=%{ocaml:native}%","OCAML_NATIVE_TOOLS=%{ocaml:native}%"],[{"id":"make"},"check-if-preinstalled","all","opam-install"]],"conflicts":["base-ocamlbuild",{"conditions":[{"arg":"1.6.2","prefix_relop":"lt"}],"val":"ocamlfind"}],"depends":[{"conditions":[{"arg":"4.03","prefix_relop":"geq"}],"val":"ocaml"}],"dev-repo":"git+https://github.com/ocaml/ocamlbuild.git","doc":"https://github.com/ocaml/ocamlbuild/blob/master/manual/manual.adoc","files-contents":{},"homepage":"https://github.com/ocaml/ocamlbuild/","isLocal":false,"license":"LGPL-2.0-or-later WITH OCaml-LGPL-linking-exception","maintainer":"Gabriel Scherer <gabriel.scherer@gmail.com>","name":"ocamlbuild","opam-version":"2.0","synopsis":"OCamlbuild is a build system with builtin rules to easily build most OCaml projects","url":{"section":{"checksum":["md5=2f407fadd57b073155a6aead887d9676","sha512=f568bf10431a1f701e8bd7554dc662400a0d978411038bbad93d44dceab02874490a8a5886a9b44e017347e7949997f13f5c3752f74e1eb5e273d2beb19a75fd"],"src":"https://github.com/ocaml/ocamlbuild/archive/refs/tags/0.14.2.tar.gz"}},"version":"0.14.2"},"ocamlfind":{"authors":"Gerd Stolpmann <gerd@gerd-stolpmann.de>","available":{"lhs":{"id":"os"},"relop":"neq","rhs":"win32"},"bug-reports":"https://github.com/ocaml/ocamlfind/issues","build":[["./configure","-bindir",{"id":"bin"},"-sitelib",{"id":"lib"},"-mandir",{"id":"man"},"-config","%{lib}%/findlib.conf","-no-custom",{"conditions":[{"lhs":{"arg":{"id":"ocaml:preinstalled"},"pfxop":"not"},"logop":"and","rhs":{"lhs":{"id":"ocaml:version"},"relop":"geq","rhs":"4.02.0"}}],"val":"-no-camlp4"},{"conditions":[{"id":"ocaml:preinstalled"}],"val":"-no-topfind"}],[{"id":"make"},"all"],{"conditions":[{"id":"ocaml:native"}],"val":[{"id":"make"},"opt"]}],"depends":[{"conditions":[{"arg":"3.08.0","prefix_relop":"geq"}],"val":"ocaml"}],"depopts":["graphics"],"description":"\nFindlib is a library manager for OCaml. It provides a convention how\nto store libraries, and a file format (\"META\") to describe the\nproperties of libraries. There is also a tool (ocamlfind) for\ninterpreting the META files, so that it is very easy to use libraries\nin programs and scripts.\n","dev-repo":"git+https://github.com/ocaml/ocamlfind.git","extra-files":["0001-Harden-test-for-OCaml-5.patch","md5=3cddbf72164c29d4e50e077a92a37c6c"],"files-contents":{"0001-Harden-test-for-OCaml-5.patch":"diff a/configure b/configure\n--- a/configure\n+++ b/configure\n@@ -294,7 +294,7 @@\n # If findlib has been configured -sitelib $(ocamlc -where) then there's\n # nothing to do, but otherwise we need to put OCaml's Standard Library\n # into the path setting.\n- if [ ! -e \"${ocaml_sitelib}/stdlib/META\" ]; then\n+ if [ ! -e \"${ocaml_sitelib}/stdlib.cmi\" ]; then\n ocamlpath=\"${ocaml_core_stdlib}${path_sep}${ocamlpath}\"\n fi\n fi\n"},"homepage":"http://projects.camlcity.org/projects/findlib.html","install":[[{"id":"make"},"install"],{"conditions":[{"id":"ocaml:preinstalled"}],"val":["install","-m","0755","ocaml-stub","%{bin}%/ocaml"]}],"isLocal":false,"license":"MIT","maintainer":"Thomas Gazagnaire <thomas@gazagnaire.org>","name":"ocamlfind","opam-version":"2.0","patches":["0001-Harden-test-for-OCaml-5.patch"],"synopsis":"A library manager for OCaml","url":{"section":{"checksum":["md5=96c6ee50a32cca9ca277321262dbec57","sha512=cfaf1872d6ccda548f07d32cc6b90c3aafe136d2aa6539e03143702171ee0199add55269bba894c77115535dc46a5835901a5d7c75768999e72db503bfd83027"],"src":"http://download.camlcity.org/download/findlib-1.9.6.tar.gz"}},"version":"1.9.6"},"ocplib-endian":{"authors":"Pierre Chambart","bug-reports":"https://github.com/OCamlPro/ocplib-endian/issues","build":["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}],"depends":["base-bytes",{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"1.1.0","prefix_relop":"geq"},"logop":"and","rhs":{"id":"build"}}],"val":"cppo"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"}],"description":"The library implements three modules:\n* [EndianString](https://github.com/OCamlPro/ocplib-endian/blob/master/src/endianString.mli) works directly on strings, and provides submodules BigEndian and LittleEndian, with their unsafe counter-parts;\n* [EndianBytes](https://github.com/OCamlPro/ocplib-endian/blob/master/src/endianBytes.mli) works directly on bytes, and provides submodules BigEndian and LittleEndian, with their unsafe counter-parts;\n* [EndianBigstring](https://github.com/OCamlPro/ocplib-endian/blob/master/src/endianBigstring.mli) works on bigstrings (Bigarrays of chars), and provides submodules BigEndian and LittleEndian, with their unsafe counter-parts.","dev-repo":"git+https://github.com/OCamlPro/ocplib-endian.git","doc":"https://ocamlpro.github.io/ocplib-endian/ocplib-endian/","files-contents":{},"homepage":"https://github.com/OCamlPro/ocplib-endian","isLocal":false,"license":"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception","maintainer":"pierre.chambart@ocamlpro.com","name":"ocplib-endian","opam-version":"2.0","synopsis":"Optimised functions to read and write int16/32/64 from strings and bigarrays","url":{"section":{"checksum":["md5=8d5492eeb7c6815ade72a7415ea30949","sha512=2e70be5f3d6e377485c60664a0e235c3b9b24a8d6b6a03895d092c6e40d53810bfe1f292ee69e5181ce6daa8a582bfe3d59f3af889f417134f658812be5b8b85"],"src":"https://github.com/OCamlPro/ocplib-endian/archive/refs/tags/1.2.tar.gz"}},"version":"1.2"},"octavius":{"authors":["Leo White <leo@lpw25.net>"],"bug-reports":"https://github.com/ocaml-doc/octavius/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"1.11","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"}],"description":"Octavius is a library to parse the `ocamldoc` comment syntax.","dev-repo":"git+https://github.com/ocaml-doc/octavius.git","doc":"http://ocaml-doc.github.io/octavius/","files-contents":{},"homepage":"https://github.com/ocaml-doc/octavius","isLocal":false,"license":"ISC","maintainer":["leo@lpw25.net"],"name":"octavius","opam-version":"2.0","synopsis":"Ocamldoc comment syntax parser","url":{"section":{"checksum":"md5=72f9e1d996e6c5089fc513cc9218607b","src":"https://github.com/ocaml-doc/octavius/archive/v1.2.2.tar.gz"}},"version":"1.2.2"},"parsexp":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/parsexp/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"sexplib0"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nThis library provides generic parsers for parsing S-expressions from\nstrings or other medium.\n\nThe library is focused on performances but still provide full generic\nparsers that can be used with strings, bigstrings, lexing buffers,\ncharacter streams or any other sources effortlessly.\n\nIt provides three different class of parsers:\n- the normal parsers, producing [Sexp.t] or [Sexp.t list] values\n- the parsers with positions, building compact position sequences so\n that one can recover original positions in order to report properly\n located errors at little cost\n- the Concrete Syntax Tree parsers, produce values of type\n [Parsexp.Cst.t] which record the concrete layout of the s-expression\n syntax, including comments\n\nThis library is portable and doesn't provide IO functions. To read\ns-expressions from files or other external sources, you should use\nparsexp_io.\n","dev-repo":"git+https://github.com/janestreet/parsexp.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/parsexp/index.html","files-contents":{},"homepage":"https://github.com/janestreet/parsexp","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"parsexp","opam-version":"2.0","synopsis":"S-expression parsing library","url":{"section":{"checksum":"sha256=b6e2572c8e6191a85cb8f9c3276ed87fe00522c81ba7a268179fb08185e55e12","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/parsexp-v0.16.0.tar.gz"}},"version":"v0.16.0"},"pbkdf":{"authors":["Alfredo Beaumont <alfredo.beaumont@gmail.com>","Sonia Meruelo <smeruelo@gmail.com>"],"bug-reports":"https://github.com/abeaumont/ocaml-pbkdf/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-j",{"id":"jobs"},"-p",{"id":"name"},"@install"],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.07.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.8.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},"mirage-crypto",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.1","prefix_relop":"geq"}}],"val":"alcotest"}],"description":"\nAn implementation of PBKDF 1 and 2 as defined by [PKCS#5](https://tools.ietf.org/html/rfc2898) using\n [mirage-crypto](https://github.com/mirage/mirage-crypto)\n","dev-repo":"git+https://github.com/abeaumont/ocaml-pbkdf.git","doc":"https://abeaumont.github.io/ocaml-pbkdf/","files-contents":{},"homepage":"https://github.com/abeaumont/ocaml-pbkdf","isLocal":false,"license":"BSD-2-Clause","maintainer":["Alfredo Beaumont <alfredo.beaumont@gmail.com>"],"name":"pbkdf","opam-version":"2.0","synopsis":"Password based key derivation functions (PBKDF) from PKCS#5","url":{"section":{"checksum":["md5=1e0e69de61b2d9d4f9843572ecc6655c","sha512=d6f7d5efd761b87dd420ddcf97c2f9d4402dcc81d65cd1f4d81039b70c4d8c1e803bbaf4251482de8de7076da9f40b48c7eb1684e31e7a316deb5036c192bd3c"],"src":"https://github.com/abeaumont/ocaml-pbkdf/archive/1.2.0.tar.gz"}},"version":"1.2.0"},"pecu":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/mirage/pecu/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.4","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"crowbar"},{"conditions":[{"id":"with-test"}],"val":"astring"}],"description":"A non-blocking encoder/decoder of Quoted-Printable according to\nRFC2045 and RFC2047 (about encoded-word). Useful to translate contents of emails.","dev-repo":"git+https://github.com/mirage/pecu.git","doc":"https://mirage.github.io/pecu/","files-contents":{},"homepage":"https://github.com/mirage/pecu","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"pecu","opam-version":"2.0","synopsis":"Encoder/Decoder of Quoted-Printable (RFC2045 & RFC2047)","url":{"section":{"checksum":["sha256=a9d2b7da444c83b20f879f6c3b7fc911d08ac1e6245ad7105437504f9394e5c7","sha512=8cae31da1fcb8b684a949846b1668131de244fbb89faf7421761da208f87092523a9e184e91a04c26739e6793501307b30ed255d540dcb268b171b7a56b56e24"],"src":"https://github.com/mirage/pecu/releases/download/v0.6/pecu-v0.6.tbz"}},"version":"0.6","x-commit-hash":"295862d499e63ef77b8fdeb08e951e6e6bdcbc42"},"ppx_assert":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_assert/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_cold"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_compare"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_here"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_sexp_conv"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_assert.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_assert/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_assert","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_assert","opam-version":"2.0","synopsis":"Assert-like extension nodes that raise useful errors on failure","url":{"section":{"checksum":"sha256=57dc6e241827eb1d5112c958f2f682ddd0addf5a8e9d589f5361ec2669883fd5","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_assert-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_base":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_base/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_cold"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_compare"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_enumerate"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_globalize"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_hash"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_sexp_conv"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nppx_base is the set of ppx rewriters used for Base.\n\nNote that Base doesn't need ppx to build, it is only used as a\nverification tool.\n","dev-repo":"git+https://github.com/janestreet/ppx_base.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_base/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_base","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_base","opam-version":"2.0","synopsis":"Base set of ppx rewriters","url":{"section":{"checksum":"sha256=64835763153d3262a2fa56cf307a351ebfd10cedf504c488ab3bb93f3d9569a3","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_base-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_cold":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_cold/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_cold.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_cold/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_cold","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_cold","opam-version":"2.0","synopsis":"Expands [@cold] into [@inline never][@specialise never][@local never]","url":{"section":{"checksum":"sha256=803bdb583b501aa246d8ae34be0c16b892d8ae96852bb593f3e355232e6aa4da","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_cold-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_compare":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_compare/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_compare.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_compare/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_compare","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_compare","opam-version":"2.0","synopsis":"Generation of comparison functions from types","url":{"section":{"checksum":"sha256=7ac1dd852e62de6c4b6a879b8bd962c0167db822c39e8c972c8a6af4c48f26aa","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_compare-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_derivers":{"authors":["Jérémie Dimino"],"bug-reports":"https://github.com/ocaml-ppx/ppx_derivers/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":["ocaml","dune"],"description":"\nPpx_derivers is a tiny package whose sole purpose is to allow\nppx_deriving and ppx_type_conv to inter-operate gracefully when linked\nas part of the same ocaml-migrate-parsetree driver.","dev-repo":"git+https://github.com/ocaml-ppx/ppx_derivers.git","files-contents":{},"homepage":"https://github.com/ocaml-ppx/ppx_derivers","isLocal":false,"license":"BSD-3-Clause","maintainer":"jeremie@dimino.org","name":"ppx_derivers","opam-version":"2.0","synopsis":"Shared [@@deriving] plugin registry","url":{"section":{"checksum":"md5=5dc2bf130c1db3c731fe0fffc5648b41","src":"https://github.com/ocaml-ppx/ppx_derivers/archive/1.2.1.tar.gz"}},"version":"1.2.1"},"ppx_deriving":{"authors":["whitequark <whitequark@whitequark.org>"],"bug-reports":"https://github.com/ocaml-ppx/ppx_deriving/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"ocaml:version"},"relop":"lt","rhs":"5.0.0"}}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]},{"conditions":[{"id":"with-doc"}],"val":["dune","build","@doc","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.05.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.6.3","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.1.0","prefix_relop":"geq"}}],"val":"cppo"},"ocamlfind","ppx_derivers",{"conditions":[{"arg":"0.20.0","prefix_relop":"geq"}],"val":"ppxlib"},"result",{"conditions":[{"id":"with-test"}],"val":"ounit2"}],"description":"\nppx_deriving provides common infrastructure for generating\ncode based on type definitions, and a set of useful plugins\nfor common tasks.\n","dev-repo":"git+https://github.com/ocaml-ppx/ppx_deriving.git","doc":"https://ocaml-ppx.github.io/ppx_deriving/","files-contents":{},"homepage":"https://github.com/ocaml-ppx/ppx_deriving","isLocal":false,"license":"MIT","maintainer":"whitequark <whitequark@whitequark.org>","name":"ppx_deriving","opam-version":"2.0","synopsis":"Type-driven code generation for OCaml","tags":["syntax"],"url":{"section":{"checksum":["sha256=e96b5fb25b7632570e4b329e22e097fcd4b8e8680d1e43ef003a8fbd742b0786","sha512=f28cd778a2d48ababa53f73131b25229a11b03685610d020b7b9228b1e25570891cd927b37475aeda49be72debaf5f2dda4c1518a0965db7a361c0ebe325a8d2"],"src":"https://github.com/ocaml-ppx/ppx_deriving/releases/download/v5.2.1/ppx_deriving-v5.2.1.tbz"}},"version":"5.2.1","x-commit-hash":"7211546d6527bf57d3eff8174c90fc3c22250dae"},"ppx_enumerate":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_enumerate/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_enumerate.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_enumerate/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_enumerate","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_enumerate","opam-version":"2.0","synopsis":"Generate a list containing all values of a finite type","url":{"section":{"checksum":"sha256=2832635d6d9ac4c63d48ed51d72745cd8a548e226a6110909d5a412d40ef9953","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_enumerate-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_globalize":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_globalize/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_globalize.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_globalize/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_globalize","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_globalize","opam-version":"2.0","synopsis":"A ppx rewriter that generates functions to copy local values to the global heap","url":{"section":{"checksum":"sha256=9068d7b4b765112974b17dd354cadf007f044afb11d2f99cd45b2e3b99ab491b","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_globalize-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_hash":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_hash/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_compare"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_sexp_conv"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_hash.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_hash/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_hash","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_hash","opam-version":"2.0","synopsis":"A ppx rewriter that generates hash functions from type expressions and definitions","url":{"section":{"checksum":"sha256=9b012546b7b9278bfd536f802fb6da88a11ebb5340d8aa47e9bf49acbf13b6e5","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_hash-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_here":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_here/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_here.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_here/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_here","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_here","opam-version":"2.0","synopsis":"Expands [%here] into its location","url":{"section":{"checksum":"sha256=278198b92500c306fab3411e3dede264d678f203eb3295dd8dd79b70ed9273f0","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_here-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_inline_test":{"authors":["Jane Street Group, LLC"],"available":{"lhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"arm32"},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"neq","rhs":"x86_32"}},"bug-reports":"https://github.com/janestreet/ppx_inline_test/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"time_now"},{"conditions":[{"arg":"3.11.1","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_inline_test.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_inline_test/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_inline_test","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_inline_test","opam-version":"2.0","synopsis":"Syntax extension for writing in-line tests in ocaml code","url":{"section":{"checksum":["md5=470acc022eb7015862307dad8fe9bcba","sha512=f82d6d9fe6d84b837d69eb35cc92e2a0b6d0802079437e291aa350b89af1df54a996d6c7843019d488a3afe1e635da070f7ca80595dfdfd8257b2d0722725bf9"],"src":"https://github.com/janestreet/ppx_inline_test/archive/refs/tags/v0.16.1.tar.gz"}},"version":"v0.16.1"},"ppx_js_style":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_js_style/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},"octavius",{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n\nThis packages is a no-op ppx rewriter. It is used as a 'lint' tool to\nenforce some coding conventions across all Jane Street packages.\n","dev-repo":"git+https://github.com/janestreet/ppx_js_style.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_js_style/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_js_style","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_js_style","opam-version":"2.0","synopsis":"Code style checker for Jane Street Packages","url":{"section":{"checksum":"sha256=a63789aaf1b2301d60d29a67f8bae9ba127d98a4f004ab9567b8f16b3c885de0","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_js_style-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_optcomp":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_optcomp/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"stdio"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_optcomp.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_optcomp/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_optcomp","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_optcomp","opam-version":"2.0","synopsis":"Optional compilation for OCaml","url":{"section":{"checksum":"sha256=99b209084a5375dafce4c6b128979661ab2ab6bf898a6872d596e65ded590ba2","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_optcomp-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_sexp_conv":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_sexp_conv/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"sexplib0"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_sexp_conv.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_sexp_conv/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_sexp_conv","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_sexp_conv","opam-version":"2.0","synopsis":"[@@deriving] plugin to generate S-expression conversion functions","url":{"section":{"checksum":"sha256=41bcb7a3b33bdf50428408bfaf1dbcede528a488ac8c436ce710681bcd91200d","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_sexp_conv-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_yojson_conv":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_yojson_conv/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_js_style"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_yojson_conv_lib"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"0.28.0","prefix_relop":"geq"}],"val":"ppxlib"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_yojson_conv.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_yojson_conv/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_yojson_conv","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_yojson_conv","opam-version":"2.0","synopsis":"[@@deriving] plugin to generate Yojson conversion functions","url":{"section":{"checksum":"sha256=4217eb9da7324c2cd086e985839fb5e6a1c2888d6a07f0b9016721a84f495ca8","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_yojson_conv-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppx_yojson_conv_lib":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/ppx_yojson_conv_lib/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"1.7.0","prefix_relop":"geq"}],"val":"yojson"}],"description":"\nPart of the Jane Street's PPX rewriters collection.\n","dev-repo":"git+https://github.com/janestreet/ppx_yojson_conv_lib.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/ppx_yojson_conv_lib/index.html","files-contents":{},"homepage":"https://github.com/janestreet/ppx_yojson_conv_lib","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"ppx_yojson_conv_lib","opam-version":"2.0","synopsis":"Runtime lib for ppx_yojson_conv","url":{"section":{"checksum":"sha256=557c43c88d365b4cbb514d809f1eecc54d7b9976b0669bc55b02169e6c86ec7d","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/ppx_yojson_conv_lib-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ppxlib":{"authors":["Jane Street Group, LLC <opensource@janestreet.com>"],"bug-reports":"https://github.com/ocaml-ppx/ppxlib/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"conflicts":[{"conditions":[{"arg":"2.0.0","prefix_relop":"lt"}],"val":"ocaml-migrate-parsetree"},"base-effects"],"depends":[{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"lhs":{"arg":"4.04.1","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"5.2.0","prefix_relop":"lt"}},"logop":"and","rhs":{"arg":"5.1.0~alpha1","prefix_relop":"neq"}}],"val":"ocaml"},{"conditions":[{"arg":"v0.11.0","prefix_relop":"geq"}],"val":"ocaml-compiler-libs"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"ppx_derivers"},{"conditions":[{"arg":"v0.12","prefix_relop":"geq"}],"val":"sexplib0"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.15","prefix_relop":"geq"}}],"val":"sexplib0"},"stdlib-shims",{"conditions":[{"id":"with-test"}],"val":"ocamlfind"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.9.0","prefix_relop":"geq"}}],"val":"re"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.12.1","prefix_relop":"geq"}}],"val":"cinaps"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nPpxlib is the standard infrastructure for ppx rewriters\nand other programs that manipulate the in-memory representation of\nOCaml programs, a.k.a the \"Parsetree\".\n\nIt also comes bundled with two ppx rewriters that are commonly used to\nwrite tools that manipulate and/or generate Parsetree values;\n`ppxlib.metaquot` which allows to construct Parsetree values using the\nOCaml syntax directly and `ppxlib.traverse` which provides various\nways of automatically traversing values of a given type, in particular\nallowing to inject a complex structured value into generated code.\n","dev-repo":"git+https://github.com/ocaml-ppx/ppxlib.git","doc":"https://ocaml-ppx.github.io/ppxlib/","files-contents":{},"homepage":"https://github.com/ocaml-ppx/ppxlib","isLocal":false,"license":"MIT","maintainer":["opensource@janestreet.com"],"name":"ppxlib","opam-version":"2.0","synopsis":"Standard infrastructure for ppx rewriters","url":{"section":{"checksum":["sha256=d21676654e57faa12d7895caffe8703b64521d66efcf152491871a55b2ae41d8","sha512=63f2d327cfc5382476f812670d304aade91b3ea8f10420d6fc9e7078112368d99dbf43dfda9c2c2cf91341b71c37c45c1fe1d54fecde2348560f9d3c48571603"],"src":"https://github.com/ocaml-ppx/ppxlib/releases/download/0.31.0/ppxlib-0.31.0.tbz"}},"version":"0.31.0","x-commit-hash":"e765a30151347f8044ce077d103d3828db8d5409"},"prettym":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/dinosaure/prettym/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.8","prefix_relop":"geq"}],"val":"dune"},"bigarray-overlap",{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},{"conditions":[{"arg":"0.4","prefix_relop":"geq"}],"val":"ke"},{"conditions":[{"arg":"0.2","prefix_relop":"geq"}],"val":"bigstringaf"},{"conditions":[{"id":"with-test"}],"val":"ptime"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"jsonm"},{"conditions":[{"id":"with-test"}],"val":"base64"}],"description":"A best effort memory-bounded encoder to respect the 80 column limitation","dev-repo":"git+https://github.com/dinosaure/prettym.git","doc":"https://dinosaure.github.io/prettym/","files-contents":{},"homepage":"https://github.com/dinosaure/prettym","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"prettym","opam-version":"2.0","synopsis":"An memory-bounded encoder according to RFC 822","url":{"section":{"checksum":["sha256=9170f1a11ade7f4d98a584a5be52bb6b91415f971c6e75894331b46b18b98f09","sha512=ccb5985daedfb6cae74192090644e81c525df3e0653bb06492f836ca4291275d3ce75079237574200ecab8dacf62304521592d4baebbe4b0d17277b5e200c6a8"],"src":"https://github.com/dinosaure/prettym/releases/download/0.0.3/prettym-0.0.3.tbz"}},"version":"0.0.3","x-commit-hash":"a22c4d46c11e2c4c0605ff7151b957785c795593"},"psq":{"authors":["David Kaloper Meršinjak <dk505@cam.ac.uk>"],"bug-reports":"https://github.com/pqwy/psq/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"ocaml:version"},"relop":"geq","rhs":"4.07.0"}}],"val":["dune","runtest","-p",{"id":"name"}]}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.7","prefix_relop":"geq"}],"val":"dune"},"seq",{"conditions":[{"id":"with-test"}],"val":"qcheck-core"},{"conditions":[{"id":"with-test"}],"val":"qcheck-alcotest"},{"conditions":[{"id":"with-test"}],"val":"alcotest"}],"description":"\nTypical applications are searches, schedulers and caches. If you ever scratched\nyour head because that A* didn't look quite right, a PSQ is what you needed.\n","dev-repo":"git+https://github.com/pqwy/psq.git","doc":"https://pqwy.github.io/psq/doc","files-contents":{},"homepage":"https://github.com/pqwy/psq","isLocal":false,"license":"ISC","maintainer":"David Kaloper Meršinjak <dk505@cam.ac.uk>","name":"psq","opam-version":"2.0","synopsis":"Functional Priority Search Queues","url":{"section":{"checksum":["sha256=42005f533eabe74b1799ee32b8905654cd66a22bed4af2bd266b28d8462cd344","sha512=8a8dfe20dc77e1cf38a7b1a7fc76f815c71a4ffe04627151b855feaba8f1ae742594739d1b7a45580b5b24a2cd99b58516f6b5c8d858aa314201f4a6422101ee"],"src":"https://github.com/pqwy/psq/releases/download/v0.2.1/psq-0.2.1.tbz"}},"version":"0.2.1","x-commit-hash":"b2eb86165712da210bcffec385bb7e031e54045e"},"ptime":{"authors":"The ptime programmers","bug-reports":"https://github.com/dbuenzli/ptime/issues","build":["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%"],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"0.9.0","prefix_relop":"neq"}}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"}],"description":"Ptime has platform independent POSIX time support in pure OCaml. It\nprovides a type to represent a well-defined range of POSIX timestamps\nwith picosecond precision, conversion with date-time values,\nconversion with [RFC 3339 timestamps][rfc3339] and pretty printing to\na human-readable, locale-independent representation.\n\nThe additional Ptime_clock library provides access to a system POSIX\nclock and to the system's current time zone offset.\n\nPtime is not a calendar library.\n\nPtime has no dependency. Ptime_clock depends on your system library or\nJavaScript runtime system. Ptime and its libraries are distributed\nunder the ISC license.\n\n[rfc3339]: http://tools.ietf.org/html/rfc3339\n\nHome page: <http://erratique.ch/software/ptime>","dev-repo":"git+https://erratique.ch/repos/ptime.git","doc":"https://erratique.ch/software/ptime/doc/","files-contents":{},"homepage":"https://erratique.ch/software/ptime","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"ptime","opam-version":"2.0","synopsis":"POSIX time for OCaml","tags":["time","posix","system","org:erratique"],"url":{"section":{"checksum":"sha512=309b8383f61b58840e58a82802ec8fbc61b7cc95a4590d38ad427e484cbaaf66f03fa8e6484b5b6855468a87e745aed103bf6f1041ec05062230a9fa5fb86cc6","src":"https://erratique.ch/software/ptime/releases/ptime-1.1.0.tbz"}},"version":"1.1.0"},"re":{"authors":["Jerome Vouillon","Thomas Gazagnaire","Anil Madhavapeddy","Rudi Grinberg","Gabriel Radanne"],"bug-reports":"https://github.com/ocaml/ocaml-re/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.03","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"ounit"},"seq"],"description":"\nPure OCaml regular expressions with:\n* Perl-style regular expressions (module Re.Perl)\n* Posix extended regular expressions (module Re.Posix)\n* Emacs-style regular expressions (module Re.Emacs)\n* Shell-style file globbing (module Re.Glob)\n* Compatibility layer for OCaml's built-in Str module (module Re.Str)\n","dev-repo":"git+https://github.com/ocaml/ocaml-re.git","files-contents":{},"homepage":"https://github.com/ocaml/ocaml-re","isLocal":false,"license":"LGPL-2.1-or-later WITH OCaml-LGPL-linking-exception","maintainer":"rudi.grinberg@gmail.com","name":"re","opam-version":"2.0","synopsis":"RE is a regular expression library for OCaml","url":{"section":{"checksum":["sha256=01fc244780c0f6be72ae796b1fb750f367de18624fd75d07ee79782ed6df8d4f","sha512=3e3712cc1266ec1f27620f3508ea2ebba338f4083b07d8a69dccee1facfdc1971a6c39f9deea664d2a62fd7f2cfd2eae816ca4c274acfadaee992a3befc4b757"],"src":"https://github.com/ocaml/ocaml-re/releases/download/1.11.0/re-1.11.0.tbz"}},"version":"1.11.0","x-commit-hash":"2dd38515c76c40299596d39f18d9b9a20f00d788"},"result":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/result/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":["ocaml",{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nProjects that want to use the new result type defined in OCaml >= 4.03\nwhile staying compatible with older version of OCaml should use the\nResult module defined in this library.","dev-repo":"git+https://github.com/janestreet/result.git","files-contents":{},"homepage":"https://github.com/janestreet/result","isLocal":false,"license":"BSD-3-Clause","maintainer":"Jane Street developers","name":"result","opam-version":"2.0","synopsis":"Compatibility Result module","url":{"section":{"checksum":"md5=1b82dec78849680b49ae9a8a365b831b","src":"https://github.com/janestreet/result/releases/download/1.5/result-1.5.tbz"}},"version":"1.5"},"rresult":{"authors":["The rresult programmers"],"bug-reports":"https://github.com/dbuenzli/rresult/issues","build":[["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%"]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"}],"description":"\nRresult is an OCaml module for handling computation results and errors\nin an explicit and declarative manner, without resorting to\nexceptions. It defines combinators to operate on the `result` type\navailable from OCaml 4.03 in the standard library.\n\nOCaml 4.08 provides the `Stdlib.Result` module which you should prefer\nto Rresult.\n\nRresult is distributed under the ISC license.\n\nHome page: http://erratique.ch/software/rresult \nContact: Daniel Bünzli `<daniel.buenzl i@erratique.ch>`","dev-repo":"git+https://erratique.ch/repos/rresult.git","doc":"https://erratique.ch/software/rresult/doc/Rresult","files-contents":{},"homepage":"https://erratique.ch/software/rresult","isLocal":false,"license":["ISC"],"maintainer":["Daniel Bünzli <daniel.buenzl i@erratique.ch>"],"name":"rresult","opam-version":"2.0","synopsis":"Result value combinators for OCaml","tags":["result","error","org:erratique"],"url":{"section":{"checksum":"sha512=f1bb631c986996388e9686d49d5ae4d8aaf14034f6865c62a88fb58c48ce19ad2eb785327d69ca27c032f835984e0bd2efd969b415438628a31f3e84ec4551d3","src":"https://erratique.ch/software/rresult/releases/rresult-0.7.0.tbz"}},"version":"0.7.0"},"seq":{"authors":" ","bug-reports":"https://caml.inria.fr/mantis/main_page.php","depends":[{"conditions":[{"arg":"4.07.0","prefix_relop":"geq"}],"val":"ocaml"}],"dev-repo":"git+https://github.com/ocaml/ocaml.git","extra-files":[["seq.install","md5=026b31e1df290373198373d5aaa26e42"],["META.seq","md5=b33c8a1a6c7ed797816ce27df4855107"]],"files-contents":{"META.seq":"name=\"seq\"\nversion=\"[distributed with OCaml 4.07 or above]\"\ndescription=\"dummy backward-compatibility package for iterators\"\nrequires=\"\"\n","seq.install":"lib:[\n \"META.seq\" {\"META\"}\n]\n"},"homepage":" ","isLocal":false,"maintainer":" ","name":"seq","opam-version":"2.0","synopsis":"Compatibility package for OCaml's standard iterator type starting from 4.07.","version":"base"},"sexplib":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/sexplib/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"parsexp"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"sexplib0"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"},"num"],"description":"\nPart of Jane Street's Core library\nThe Core suite of libraries is an industrial strength alternative to\nOCaml's standard library that was developed by Jane Street, the\nlargest industrial user of OCaml.\n","dev-repo":"git+https://github.com/janestreet/sexplib.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/sexplib/index.html","files-contents":{},"homepage":"https://github.com/janestreet/sexplib","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"sexplib","opam-version":"2.0","synopsis":"Library for serializing OCaml values to and from S-expressions","url":{"section":{"checksum":"sha256=e564d5d1ca157314ba5fd64b4e89fa12c6cba8efee3becf6d09d7d9dda21ac5b","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/sexplib-v0.16.0.tar.gz"}},"version":"v0.16.0"},"sexplib0":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/sexplib0/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nPart of Jane Street's Core library\nThe Core suite of libraries is an industrial strength alternative to\nOCaml's standard library that was developed by Jane Street, the\nlargest industrial user of OCaml.\n","dev-repo":"git+https://github.com/janestreet/sexplib0.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/sexplib0/index.html","files-contents":{},"homepage":"https://github.com/janestreet/sexplib0","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"sexplib0","opam-version":"2.0","synopsis":"Library containing the definition of S-expressions and some base converters","url":{"section":{"checksum":"sha256=86dba26468194512f789f2fb709063515a9cb4e5c4461c021c239a369590701d","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/sexplib0-v0.16.0.tar.gz"}},"version":"v0.16.0"},"ssl":{"authors":["Samuel Mimram <samuel.mimram@ens-lyon.org>"],"bug-reports":"https://github.com/savonet/ocaml-ssl/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"ocaml:version"},"relop":"geq","rhs":"4.08.0"}}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},"dune-configurator","conf-libssl",{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"dev"},"logop":"and","rhs":{"arg":"2.5.0","prefix_relop":"geq"}}],"val":"bisect_ppx"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"dev-repo":"git+https://github.com/savonet/ocaml-ssl.git","files-contents":{},"homepage":"https://github.com/savonet/ocaml-ssl","isLocal":false,"license":"LGPL-2.1-only WITH OCaml-LGPL-linking-exception","maintainer":["Antonio Monteiro <anmonteiro@gmail.com>"],"name":"ssl","opam-version":"2.0","synopsis":"Bindings for OpenSSL","url":{"section":{"checksum":["md5=0ced13c2beef2135cd9d3a3743ea0e37","sha512=969c4d64828449a49bdef26ca5f8faa72d2fe2a2304ccbf589a3ff097c2bf8ae9eb83ae1c90216f6b4d6f359e462ea47e0106a7386e26848d14910138fcb07f8"],"src":"https://github.com/savonet/ocaml-ssl/archive/refs/tags/v0.7.0.tar.gz"}},"version":"0.7.0"},"stdio":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/stdio/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nStdio implements simple input/output functionalities for OCaml.\n\nIt re-exports the input/output functions of the OCaml standard\nlibraries using a more consistent API.\n","dev-repo":"git+https://github.com/janestreet/stdio.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/stdio/index.html","files-contents":{},"homepage":"https://github.com/janestreet/stdio","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"stdio","opam-version":"2.0","synopsis":"Standard IO library for OCaml","url":{"section":{"checksum":"sha256=61f0b75950614ac5378c6ec0d822cce6463402d919d5810b736fc46522b3a73e","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/stdio-v0.16.0.tar.gz"}},"version":"v0.16.0"},"stdlib-shims":{"authors":"The stdlib-shims programmers","bug-reports":"https://github.com/ocaml/stdlib-shims/issues","build":["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],"depends":["dune",{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"}],"description":"\nBackport some of the new stdlib features to older compiler,\nsuch as the Stdlib module.\n\nThis allows projects that require compatibility with older compiler to\nuse these new features in their code.\n","dev-repo":"git+https://github.com/ocaml/stdlib-shims.git","doc":"https://ocaml.github.io/stdlib-shims/","files-contents":{},"homepage":"https://github.com/ocaml/stdlib-shims","isLocal":false,"license":["LGPL-2.1-only WITH OCaml-LGPL-linking-exception"],"maintainer":"The stdlib-shims programmers","name":"stdlib-shims","opam-version":"2.0","synopsis":"Backport some of the new stdlib features to older compiler","tags":["stdlib","compatibility","org:ocaml"],"url":{"section":{"checksum":["sha256=babf72d3917b86f707885f0c5528e36c63fccb698f4b46cf2bab5c7ccdd6d84a","sha512=1151d7edc8923516e9a36995a3f8938d323aaade759ad349ed15d6d8501db61ffbe63277e97c4d86149cf371306ac23df0f581ec7e02611f58335126e1870980"],"src":"https://github.com/ocaml/stdlib-shims/releases/download/0.3.0/stdlib-shims-0.3.0.tbz"}},"version":"0.3.0","x-commit-hash":"fb6815e5d745f07fd567c11671149de6ef2e74c8"},"stringext":{"authors":"Rudi Grinberg","bug-reports":"https://github.com/rgrinberg/stringext/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"id":"with-test"}],"val":"ounit"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"2.2","prefix_relop":"geq"}}],"val":"qtest"}],"description":"\nExtra string functions for OCaml. Mainly splitting. All functions are in the\nStringext module.\n","dev-repo":"git+https://github.com/rgrinberg/stringext.git","files-contents":{},"homepage":"https://github.com/rgrinberg/stringext","isLocal":false,"license":"MIT","maintainer":"rudi.grinberg@gmail.com","name":"stringext","opam-version":"2.0","synopsis":"Extra string functions for OCaml","url":{"section":{"checksum":["sha256=db41f5d52e9eab17615f110b899dfeb27dd7e7f89cd35ae43827c5119db206ea","sha512=d8ebe40f42b598a9bd99f1ef4b00ba93458385a4accd121af66a0bf3b3f8d7135f576740adf1a43081dd409977c2219fd4bdbb5b3d1308890d301d553ed49900"],"src":"https://github.com/rgrinberg/stringext/releases/download/1.6.0/stringext-1.6.0.tbz"}},"version":"1.6.0"},"time_now":{"authors":["Jane Street Group, LLC"],"bug-reports":"https://github.com/janestreet/time_now/issues","build":[["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}]],"depends":[{"conditions":[{"arg":"4.14.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"jane-street-headers"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"jst-config"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_base"},{"conditions":[{"lhs":{"arg":"v0.16","prefix_relop":"geq"},"logop":"and","rhs":{"arg":"v0.17","prefix_relop":"lt"}}],"val":"ppx_optcomp"},{"conditions":[{"arg":"2.0.0","prefix_relop":"geq"}],"val":"dune"}],"description":"\nProvides a single function to report the current time in nanoseconds\nsince the start of the Unix epoch.\n","dev-repo":"git+https://github.com/janestreet/time_now.git","doc":"https://ocaml.janestreet.com/ocaml-core/latest/doc/time_now/index.html","files-contents":{},"homepage":"https://github.com/janestreet/time_now","isLocal":false,"license":"MIT","maintainer":"Jane Street developers","name":"time_now","opam-version":"2.0","synopsis":"Reports the current time","url":{"section":{"checksum":"sha256=5fa084aadee6aaedbb8976e4a2bc0c1dfe69eecdd0576ff901f21eedd46dc3a1","src":"https://ocaml.janestreet.com/ocaml-core/v0.16/files/time_now-v0.16.0.tar.gz"}},"version":"v0.16.0"},"topkg":{"authors":"The topkg programmers","bug-reports":"https://github.com/dbuenzli/topkg/issues","build":["ocaml","pkg/pkg.ml","build","--pkg-name",{"id":"name"},"--dev-pkg","%{dev}%"],"depends":[{"conditions":[{"arg":"4.05.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.6.1","prefix_relop":"geq"}}],"val":"ocamlfind"},"ocamlbuild"],"description":"Topkg is a packager for distributing OCaml software. It provides an\nAPI to describe the files a package installs in a given build\nconfiguration and to specify information about the package's\ndistribution, creation and publication procedures.\n\nThe optional topkg-care package provides the `topkg` command line tool\nwhich helps with various aspects of a package's life cycle: creating\nand linting a distribution, releasing it on the WWW, publish its\ndocumentation, add it to the OCaml opam repository, etc.\n\nTopkg is distributed under the ISC license and has **no**\ndependencies. This is what your packages will need as a *build*\ndependency.\n\nTopkg-care is distributed under the ISC license it depends on\n[fmt][fmt], [logs][logs], [bos][bos], [cmdliner][cmdliner],\n[webbrowser][webbrowser] and `opam-format`.\n\n[fmt]: http://erratique.ch/software/fmt\n[logs]: http://erratique.ch/software/logs\n[bos]: http://erratique.ch/software/bos\n[cmdliner]: http://erratique.ch/software/cmdliner\n[webbrowser]: http://erratique.ch/software/webbrowser\n\nHome page: http://erratique.ch/software/topkg","dev-repo":"git+https://erratique.ch/repos/topkg.git","doc":"https://erratique.ch/software/topkg/doc","files-contents":{},"homepage":"https://erratique.ch/software/topkg","isLocal":false,"license":"ISC","maintainer":"Daniel Bünzli <daniel.buenzl i@erratique.ch>","name":"topkg","opam-version":"2.0","synopsis":"The transitory OCaml software packager","tags":["packaging","ocamlbuild","org:erratique"],"url":{"section":{"checksum":"sha512=09e59f1759bf4db8471f02d0aefd8db602b44932a291c05c312b1423796e7a15d1598d3c62a0cec7f083eff8e410fac09363533dc4bd2120914bb9664efea535","src":"https://erratique.ch/software/topkg/releases/topkg-1.0.7.tbz"}},"version":"1.0.7"},"unstrctrd":{"authors":"Romain Calascibetta <romain.calascibetta@gmail.com>","bug-reports":"https://github.com/dinosaure/unstrctrd/issues","build":["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],"depends":[{"conditions":[{"arg":"4.07.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"2.0","prefix_relop":"geq"}],"val":"dune"},"uutf",{"conditions":[{"arg":"0.14.0","prefix_relop":"geq"}],"val":"angstrom"},{"conditions":[{"id":"with-test"}],"val":"rresult"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"id":"with-test"}],"val":"ke"},{"conditions":[{"id":"with-test"}],"val":"bigstringaf"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.3.1","prefix_relop":"geq"}}],"val":"hxd"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.7","prefix_relop":"geq"}}],"val":"fmt"},{"conditions":[{"lhs":{"arg":"0.2","prefix_relop":"geq"},"logop":"and","rhs":{"id":"with-test"}}],"val":"crowbar"}],"description":"Fast and compliant Unstructured parser according RFC 822","dev-repo":"git+https://github.com/dinosaure/unstrctrd.git","doc":"https://dinosaure.github.io/unstrctrd/","files-contents":{},"homepage":"https://github.com/dinosaure/unstrctrd","isLocal":false,"license":"MIT","maintainer":"Romain Calascibetta <romain.calascibetta@gmail.com>","name":"unstrctrd","opam-version":"2.0","run-test":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}],"synopsis":"Unstructured parser","url":{"section":{"checksum":["sha256=7355b1e9a6b977608641c88f9f136fff309ef64e174818c7ccadc8a2a78ded5b","sha512=ea2289a331b08523ffcd135e03a4e9fbbc27b46496a1b7dbdd95a0dad57f83cc9b59393ff9a14e557952ad466a2608e60801365993cb22ec79c4650831b620ab"],"src":"https://github.com/dinosaure/unstrctrd/releases/download/v0.3/unstrctrd-v0.3.tbz"}},"version":"0.3","x-commit-hash":"92bb3ea3073ed6dbd4c9b75670a41b7781f5c1d4"},"uri":{"authors":["Anil Madhavapeddy","David Sheets","Rudi Grinberg"],"bug-reports":"https://github.com/mirage/ocaml-uri/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"}}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"1.0.2","prefix_relop":"geq"}}],"val":"ounit2"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"v0.9.0","prefix_relop":"geq"}}],"val":"ppx_sexp_conv"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.2","prefix_relop":"geq"}}],"val":"crowbar"},{"conditions":[{"arg":"1.4.0","prefix_relop":"geq"}],"val":"stringext"},{"conditions":[{"arg":"0.14.0","prefix_relop":"geq"}],"val":"angstrom"}],"description":"\nThis is an OCaml implementation of the [RFC3986](http://tools.ietf.org/html/rfc3986) specification\nfor parsing URI or URLs.\n","dev-repo":"git+https://github.com/mirage/ocaml-uri.git","doc":"https://mirage.github.io/ocaml-uri/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-uri","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"uri","opam-version":"2.0","synopsis":"An RFC3986 URI/URL parsing library","tags":["url","uri","org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=cdabaf6ef5cd2161e59cc7b74c6e4a68ecb80a9f4e96002e338e1b6bf17adec4","sha512=88374143e0d8aaf6d40aa3cbd7593f9832e9c9727738c6e651498125150c83d5646e13b5737d5c3e81484dd041127f67f8acea13fdc0300ac4e46107559f8ae2"],"src":"https://github.com/mirage/ocaml-uri/releases/download/v4.4.0/uri-4.4.0.tbz"}},"version":"4.4.0","x-commit-hash":"c336c796f4deb8979a4c7ceea3bef34b46240623"},"uri-sexp":{"authors":["Anil Madhavapeddy","David Sheets","Rudi Grinberg"],"bug-reports":"https://github.com/mirage/ocaml-uri/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"depends":[{"conditions":[{"arg":{"id":"version"},"prefix_relop":"eq"}],"val":"uri"},{"conditions":[{"arg":"1.2.0","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"v0.13.0","prefix_relop":"geq"}],"val":"ppx_sexp_conv"},"sexplib0",{"conditions":[{"id":"with-test"}],"val":"ounit2"}],"description":"\nocaml-uri with sexp support\n","dev-repo":"git+https://github.com/mirage/ocaml-uri.git","doc":"https://mirage.github.io/ocaml-uri/","files-contents":{},"homepage":"https://github.com/mirage/ocaml-uri","isLocal":false,"license":"ISC","maintainer":"anil@recoil.org","name":"uri-sexp","opam-version":"2.0","synopsis":"An RFC3986 URI/URL parsing library","tags":["url","uri","org:mirage","org:xapi-project"],"url":{"section":{"checksum":["sha256=cdabaf6ef5cd2161e59cc7b74c6e4a68ecb80a9f4e96002e338e1b6bf17adec4","sha512=88374143e0d8aaf6d40aa3cbd7593f9832e9c9727738c6e651498125150c83d5646e13b5737d5c3e81484dd041127f67f8acea13fdc0300ac4e46107559f8ae2"],"src":"https://github.com/mirage/ocaml-uri/releases/download/v4.4.0/uri-4.4.0.tbz"}},"version":"4.4.0","x-commit-hash":"c336c796f4deb8979a4c7ceea3bef34b46240623"},"uutf":{"authors":["The uutf programmers"],"bug-reports":"https://github.com/dbuenzli/uutf/issues","build":[["ocaml","pkg/pkg.ml","build","--dev-pkg","%{dev}%","--with-cmdliner","%{cmdliner:installed}%"]],"conflicts":[{"conditions":[{"arg":"0.9.8","prefix_relop":"lt"}],"val":"cmdliner"}],"depends":[{"conditions":[{"arg":"4.03.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"ocamlfind"},{"conditions":[{"id":"build"}],"val":"ocamlbuild"},{"conditions":[{"lhs":{"id":"build"},"logop":"and","rhs":{"arg":"1.0.3","prefix_relop":"geq"}}],"val":"topkg"}],"depopts":["cmdliner"],"description":"\nUutf is a non-blocking streaming codec to decode and encode the UTF-8,\nUTF-16, UTF-16LE and UTF-16BE encoding schemes. It can efficiently\nwork character by character without blocking on IO. Decoders perform\ncharacter position tracking and support newline normalization.\n\nFunctions are also provided to fold over the characters of UTF encoded\nOCaml string values and to directly encode characters in OCaml\nBuffer.t values. **Note** that since OCaml 4.14, that functionality\ncan be found in the Stdlib and you are encouraged to migrate to it.\n\nUutf has no dependency and is distributed under the ISC license.\n\nHome page: http://erratique.ch/software/uutf \nContact: Daniel Bünzli `<daniel.buenzl i@erratique.ch>`","dev-repo":"git+https://erratique.ch/repos/uutf.git","doc":"https://erratique.ch/software/uutf/doc/","files-contents":{},"homepage":"https://erratique.ch/software/uutf","isLocal":false,"license":["ISC"],"maintainer":["Daniel Bünzli <daniel.buenzl i@erratique.ch>"],"name":"uutf","opam-version":"2.0","synopsis":"Non-blocking streaming Unicode codec for OCaml","tags":["unicode","text","utf-8","utf-16","codec","org:erratique"],"url":{"section":{"checksum":"sha512=50cc4486021da46fb08156e9daec0d57b4ca469b07309c508d5a9a41e9dbcf1f32dec2ed7be027326544453dcaf9c2534919395fd826dc7768efc6cc4bfcc9f8","src":"https://erratique.ch/software/uutf/releases/uutf-1.0.3.tbz"}},"version":"1.0.3"},"x509":{"authors":["Hannes Mehnert <hannes@mehnert.org>","David Kaloper <dk505@cam.ac.uk>"],"bug-reports":"https://github.com/mirleft/ocaml-x509/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"}],{"conditions":[{"id":"with-test"}],"val":["dune","runtest","-p",{"id":"name"},"-j",{"id":"jobs"}]}],"conflicts":[{"conditions":[{"arg":"1.5","prefix_relop":"lt"}],"val":"result"}],"depends":[{"conditions":[{"arg":"4.08.0","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"arg":"1.2","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"6.0.0","prefix_relop":"geq"}],"val":"cstruct"},{"conditions":[{"arg":"0.2.0","prefix_relop":"geq"}],"val":"asn1-combinators"},"ptime",{"conditions":[{"arg":"3.3.0","prefix_relop":"geq"}],"val":"base64"},"mirage-crypto","mirage-crypto-pk",{"conditions":[{"arg":"0.10.7","prefix_relop":"geq"}],"val":"mirage-crypto-ec"},"mirage-crypto-rng",{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.11.0","prefix_relop":"geq"}}],"val":"mirage-crypto-rng"},{"conditions":[{"arg":"0.8.7","prefix_relop":"geq"}],"val":"fmt"},{"conditions":[{"id":"with-test"}],"val":"alcotest"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"3.0.0","prefix_relop":"geq"}}],"val":"cstruct-unix"},{"conditions":[{"arg":"0.3.0","prefix_relop":"geq"}],"val":"gmap"},{"conditions":[{"arg":"0.3.0","prefix_relop":"geq"}],"val":"domain-name"},"logs","pbkdf",{"conditions":[{"arg":"5.2.0","prefix_relop":"geq"}],"val":"ipaddr"}],"description":"\nX.509 is a public key infrastructure used mostly on the Internet. It consists\nof certificates which include public keys and identifiers, signed by an\nauthority. Authorities must be exchanged over a second channel to establish the\ntrust relationship. This library implements most parts of RFC5280 and RFC6125.\nThe Public Key Cryptography Standards (PKCS) defines encoding and decoding\n(in ASN.1 DER and PEM format), which is also implemented by this library -\nnamely PKCS 1, PKCS 5, PKCS 7, PKCS 8, PKCS 9, PKCS 10, and PKCS 12.\n","dev-repo":"git+https://github.com/mirleft/ocaml-x509.git","doc":"https://mirleft.github.io/ocaml-x509/doc","files-contents":{},"homepage":"https://github.com/mirleft/ocaml-x509","isLocal":false,"license":"BSD-2-Clause","maintainer":["Hannes Mehnert <hannes@mehnert.org>"],"name":"x509","opam-version":"2.0","synopsis":"Public Key Infrastructure (RFC 5280, PKCS) purely in OCaml","tags":"org:mirage","url":{"section":{"checksum":["sha256=149e25a5fea37f619fb2690bee5c00f01c9dcf31d335f8ffcaab39a7538ccd99","sha512=6dd494dba799eab7edde2af1b63bac6035bf4ae06f3a36dd4fa9abcd13d0c3fe3e93dc5848b65405dc5401b1755fd30c71482cb91f7495bc9cfb7c5bf15ef6d7"],"src":"https://github.com/mirleft/ocaml-x509/releases/download/v0.16.5/x509-0.16.5.tbz"}},"version":"0.16.5","x-commit-hash":"b00656d2952282323604765d504dfea067b17879"},"yojson":{"authors":["Martin Jambon"],"bug-reports":"https://github.com/ocaml-community/yojson/issues","build":[{"conditions":[{"id":"dev"}],"val":["dune","subst"]},["dune","build","-p",{"id":"name"},"-j",{"id":"jobs"},"@install",{"conditions":[{"id":"with-test"}],"val":"@runtest"},{"conditions":[{"id":"with-doc"}],"val":"@doc"}]],"depends":[{"conditions":[{"arg":"2.7","prefix_relop":"geq"}],"val":"dune"},{"conditions":[{"arg":"4.02.3","prefix_relop":"geq"}],"val":"ocaml"},{"conditions":[{"id":"build"}],"val":"cppo"},{"conditions":[{"lhs":{"id":"with-test"},"logop":"and","rhs":{"arg":"0.8.5","prefix_relop":"geq"}}],"val":"alcotest"},{"conditions":[{"arg":"0.2.2","prefix_relop":"geq"}],"val":"seq"},{"conditions":[{"id":"with-doc"}],"val":"odoc"}],"description":"\nYojson is an optimized parsing and printing library for the JSON format.\n\nydump is a pretty-printing command-line program provided with the\nyojson package.","dev-repo":"git+https://github.com/ocaml-community/yojson.git","doc":"https://ocaml-community.github.io/yojson","files-contents":{},"homepage":"https://github.com/ocaml-community/yojson","isLocal":false,"license":"BSD-3-Clause","maintainer":["paul-elliot@tarides.com","nathan@tarides.com","marek@tarides.com"],"name":"yojson","opam-version":"2.0","synopsis":"Yojson is an optimized parsing and printing library for the JSON format","url":{"section":{"checksum":["sha256=59f2f1abbfc8a7ccbdbf608894e5c75e8a76006e34899254446f83e200dfb4f9","sha512=309cba7568dec51de20c7ab8df033258c275b8d58b0a36a66b26e673a3bc050cbd7e39ff8fe4796e89263e125bcc21e04dc36a394f3cc201956887eee1fb281a"],"src":"https://github.com/ocaml-community/yojson/releases/download/2.1.2/yojson-2.1.2.tbz"}},"version":"2.1.2","x-commit-hash":"e51163ee04ad79408975545ec5fc3b7dc41f68eb"},"zarith":{"authors":["Antoine Miné","Xavier Leroy","Pascal Cuoq"],"bug-reports":"https://github.com/ocaml/Zarith/issues","build":[{"conditions":[{"lhs":{"lhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"openbsd"},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"freebsd"}},"logop":"and","rhs":{"lhs":{"id":"os"},"relop":"neq","rhs":"macos"}}],"val":["./configure"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"openbsd"},"logop":"or","rhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"freebsd"}}],"val":["sh","-exc","LDFLAGS=\"$LDFLAGS -L/usr/local/lib\" CFLAGS=\"$CFLAGS -I/usr/local/include\" ./configure"]},{"conditions":[{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"neq","rhs":"homebrew"}}],"val":["sh","-exc","LDFLAGS=\"$LDFLAGS -L/opt/local/lib -L/usr/local/lib\" CFLAGS=\"$CFLAGS -I/opt/local/include -I/usr/local/include\" ./configure"]},{"conditions":[{"lhs":{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"eq","rhs":"x86_64"}}],"val":["sh","-exc","LDFLAGS=\"$LDFLAGS -L/opt/local/lib -L/usr/local/lib\" CFLAGS=\"$CFLAGS -I/opt/local/include -I/usr/local/include\" ./configure"]},{"conditions":[{"lhs":{"lhs":{"lhs":{"id":"os"},"relop":"eq","rhs":"macos"},"logop":"and","rhs":{"lhs":{"id":"os-distribution"},"relop":"eq","rhs":"homebrew"}},"logop":"and","rhs":{"lhs":{"id":"arch"},"relop":"eq","rhs":"arm64"}}],"val":["sh","-exc","LDFLAGS=\"$LDFLAGS -L/opt/homebrew/lib\" CFLAGS=\"$CFLAGS -I/opt/homebrew/include\" ./configure"]},[{"id":"make"}]],"depends":[{"conditions":[{"arg":"4.04.0","prefix_relop":"geq"}],"val":"ocaml"},"ocamlfind","conf-gmp"],"description":"\nThe Zarith library implements arithmetic and logical operations over\narbitrary-precision integers. It uses GMP to efficiently implement\narithmetic over big integers. Small integers are represented as Caml\nunboxed integers, for speed and space economy.","dev-repo":"git+https://github.com/ocaml/Zarith.git","files-contents":{},"homepage":"https://github.com/ocaml/Zarith","install":[[{"id":"make"},"install"]],"isLocal":false,"license":"LGPL-2.0-only WITH OCaml-LGPL-linking-exception","maintainer":"Xavier Leroy <xavier.leroy@inria.fr>","name":"zarith","opam-version":"2.0","synopsis":"Implements arithmetic and logical operations over arbitrary-precision integers","url":{"section":{"checksum":["md5=b3529c5de89ab8c026943f73f6195ad9","sha512=a562fa8bf4f5ef44f2af6b9a8f028182fd184c89f8c41455acdc02851cc0fc3124d3776c0de930e8d09cd5d6d88cc689f80f4b597068a0611131f45d057b101f"],"src":"https://github.com/ocaml/Zarith/archive/release-1.13.tar.gz"}},"version":"1.13"}}
\ No newline at end of file diff --git a/scripts/add-dependency.sh b/scripts/add-dependency.sh new file mode 100755 index 0000000..2f941ff --- /dev/null +++ b/scripts/add-dependency.sh @@ -0,0 +1,17 @@ +#!/bin/sh + +# This script adds a dependency to the project. +set -e + +NEW_DEP=$1 + +# Add argument to dune-project after the word (depends +# So (depends dune dream ppx becomes (depends dune dream ppx NEW_DEP +sed -i "s/\(depends.*\)/\1 $NEW_DEP/" dune-project + +# Run dune to update the project +dune build ann_bloop.opam + + +# Run cat to generate a new package-deps.json +cat $(nix eval .#package-defs --raw) > package-defs.json diff --git a/scripts/run-test-watch.sh b/scripts/run-test-watch.sh new file mode 100755 index 0000000..9190a39 --- /dev/null +++ b/scripts/run-test-watch.sh @@ -0,0 +1 @@ +dune runtest --watch --root . --profile release --no-buffer --force diff --git a/scripts/run-watch.sh b/scripts/run-watch.sh new file mode 100755 index 0000000..4558e2d --- /dev/null +++ b/scripts/run-watch.sh @@ -0,0 +1,3 @@ +#!/bin/sh + +dune exec --watch --root . --profile release -- ./bin/main.exe diff --git a/test/ann_bloop.ml b/test/ann_bloop.ml new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/test/ann_bloop.ml diff --git a/test/dune b/test/dune new file mode 100644 index 0000000..bfa3196 --- /dev/null +++ b/test/dune @@ -0,0 +1,2 @@ +(test + (name ann_bloop)) |