diff options
-rw-r--r-- | .buckconfig | 12 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | .travis.yml | 15 | ||||
-rw-r--r-- | BUCK | 60 | ||||
-rw-r--r-- | demo-cxx/BUCK | 16 | ||||
-rw-r--r-- | demo-rs/BUCK | 42 | ||||
-rw-r--r-- | third-party/.gitignore | 1 | ||||
-rw-r--r-- | third-party/BUCK | 243 | ||||
-rw-r--r-- | third-party/Cargo.lock | 434 |
9 files changed, 825 insertions, 0 deletions
diff --git a/.buckconfig b/.buckconfig new file mode 100644 index 00000000..33c15ec0 --- /dev/null +++ b/.buckconfig @@ -0,0 +1,12 @@ +[project] + # We use some symlinks in the source tree, but they get eliminated by `cargo + # publish` and `cargo vendor` so this allow_symlinks setting should not be + # required downstream. + allow_symlinks = allow + +[cxx] + cxxflags = -std=c++11 + +[rust] + default_edition = 2018 + rustc_flags = -Crelocation-model=dynamic-no-pic --cap-lints=allow @@ -1,3 +1,5 @@ +/.buckd +/buck-out /Cargo.lock /expand.cc /expand.rs diff --git a/.travis.yml b/.travis.yml index f054344a..74f438d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,18 @@ os: script: - cargo run --manifest-path demo-rs/Cargo.toml - cargo test + +matrix: + include: + - name: Buck + before_install: + - sudo apt-get install -y openjdk-8-jdk + - export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64 + - wget -O buck.deb https://github.com/facebook/buck/releases/download/v2019.10.17.01/buck.2019.10.17.01_all.deb + - sudo dpkg -i buck.deb + before_script: + - cp third-party/Cargo.lock . + - cargo vendor --versioned-dirs third-party/vendor + script: + - buck build :cxx#check --verbose=0 + - buck run demo-rs --verbose=0 @@ -0,0 +1,60 @@ +rust_library( + name = "cxx", + srcs = glob(["src/**"]), + visibility = ["PUBLIC"], + deps = [ + ":core", + ":macro", + "//third-party:anyhow", + "//third-party:cc", + "//third-party:codespan", + "//third-party:codespan-reporting", + "//third-party:link-cplusplus", + "//third-party:proc-macro2", + "//third-party:quote", + "//third-party:syn", + "//third-party:thiserror", + ], +) + +rust_binary( + name = "codegen", + srcs = glob(["cmd/src/**"]), + visibility = ["PUBLIC"], + env = { + "CARGO_PKG_AUTHORS": "David Tolnay <dtolnay@gmail.com>", + }, + deps = [ + "//third-party:anyhow", + "//third-party:codespan", + "//third-party:codespan-reporting", + "//third-party:proc-macro2", + "//third-party:quote", + "//third-party:structopt", + "//third-party:syn", + "//third-party:thiserror", + ], +) + +cxx_library( + name = "core", + srcs = ["src/cxxbridge.cc"], + visibility = ["PUBLIC"], + header_namespace = "cxxbridge", + exported_headers = { + "cxxbridge.h": "include/cxxbridge.h", + }, + exported_linker_flags = ["-lstdc++"], +) + +rust_library( + name = "macro", + srcs = glob(["macro/src/**"]), + proc_macro = True, + crate = "cxxbridge_macro", + deps = [ + "//third-party:proc-macro2", + "//third-party:quote", + "//third-party:syn", + ], +) diff --git a/demo-cxx/BUCK b/demo-cxx/BUCK new file mode 100644 index 00000000..595a18ba --- /dev/null +++ b/demo-cxx/BUCK @@ -0,0 +1,16 @@ +cxx_library( + name = "demo-cxx", + srcs = ["demo.cc"], + visibility = ["PUBLIC"], + deps = [ + ":include", + "//demo-rs:include", + ], +) + +cxx_library( + name = "include", + exported_headers = ["demo.h"], + visibility = ["PUBLIC"], + deps = ["//:core"], +) diff --git a/demo-rs/BUCK b/demo-rs/BUCK new file mode 100644 index 00000000..a0f6fb0b --- /dev/null +++ b/demo-rs/BUCK @@ -0,0 +1,42 @@ +rust_binary( + name = "demo-rs", + srcs = glob(["src/**"]), + deps = [ + ":gen", + "//:cxx", + "//demo-cxx:demo-cxx", + ], +) + +cxx_library( + name = "gen", + srcs = [":gen-source"], + deps = [ + ":include", + "//demo-cxx:include", + ], +) + +genrule( + name = "gen-header", + srcs = ["src/main.rs"], + cmd = "$(exe //:codegen) --header ${SRCS} > ${OUT}", + type = "cxxbridge", + out = "gen-demo.h", +) + +genrule( + name = "gen-source", + srcs = ["src/main.rs"], + cmd = "$(exe //:codegen) ${SRCS} > ${OUT}", + type = "cxxbridge", + out = "gen-demo.cc", +) + +cxx_library( + name = "include", + exported_headers = { + "src/main.rs": ":gen-header", + }, + visibility = ["PUBLIC"], +) diff --git a/third-party/.gitignore b/third-party/.gitignore new file mode 100644 index 00000000..61ead866 --- /dev/null +++ b/third-party/.gitignore @@ -0,0 +1 @@ +/vendor diff --git a/third-party/BUCK b/third-party/BUCK new file mode 100644 index 00000000..1c1bf3d5 --- /dev/null +++ b/third-party/BUCK @@ -0,0 +1,243 @@ +# To be generated by Facebook's `reindeer` tool once that is open source. + +rust_library( + name = "anyhow", + srcs = glob(["vendor/anyhow-1.0.26/src/**"]), + visibility = ["PUBLIC"], + features = ["std"], +) + +rust_library( + name = "bitflags", + srcs = glob(["vendor/bitflags-1.2.1/src/**"]), +) + +rust_library( + name = "cc", + srcs = glob(["vendor/cc-1.0.50/src/**"]), + visibility = ["PUBLIC"], +) + +rust_library( + name = "clap", + srcs = glob(["vendor/clap-2.33.0/src/**"]), + edition = "2015", + deps = [ + ":bitflags", + ":textwrap", + ":unicode-width", + ], +) + +rust_library( + name = "codespan", + srcs = glob(["vendor/codespan-0.7.0/src/**"]), + visibility = ["PUBLIC"], + deps = [":unicode-segmentation"], +) + +rust_library( + name = "codespan-reporting", + srcs = glob(["vendor/codespan-reporting-0.7.0/src/**"]), + visibility = ["PUBLIC"], + deps = [ + ":codespan", + ":termcolor", + ":unicode-width", + ], +) + +rust_library( + name = "heck", + srcs = glob(["vendor/heck-0.3.1/src/**"]), + edition = "2015", + deps = [":unicode-segmentation"], +) + +rust_library( + name = "lazy_static", + srcs = glob(["vendor/lazy_static-1.4.0/src/**"]), +) + +rust_library( + name = "link-cplusplus", + srcs = glob(["vendor/link-cplusplus-1.0.1/src/**"]), + visibility = ["PUBLIC"], +) + +rust_library( + name = "proc-macro-error", + srcs = glob(["vendor/proc-macro-error-0.4.9/src/**"]), + rustc_flags = ["--cfg=use_fallback"], + deps = [ + ":proc-macro-error-attr", + ":proc-macro2", + ":quote", + ":syn", + ], +) + +rust_library( + name = "proc-macro-error-attr", + srcs = glob(["vendor/proc-macro-error-attr-0.4.9/src/**"]), + proc_macro = True, + deps = [ + ":proc-macro2", + ":quote", + ":rustversion", + ":syn", + ":syn-mid", + ], +) + +rust_library( + name = "proc-macro2", + srcs = glob(["vendor/proc-macro2-1.0.8/src/**"]), + visibility = ["PUBLIC"], + features = [ + "proc-macro", + "span-locations", + ], + rustc_flags = [ + "--cfg=span_locations", + "--cfg=use_proc_macro", + "--cfg=wrap_proc_macro", + ], + deps = [":unicode-xid"], +) + +rust_library( + name = "quote", + srcs = glob(["vendor/quote-1.0.2/src/**"]), + visibility = ["PUBLIC"], + features = ["proc-macro"], + deps = [":proc-macro2"], +) + +rust_library( + name = "rustversion", + srcs = glob(["vendor/rustversion-1.0.2/src/**"]), + mapped_srcs = { + ":rustversion-buildscript-run": "vendor/rustversion-1.0.2/src/generated", + }, + proc_macro = True, + env = { + "OUT_DIR": "generated", + }, + deps = [ + ":proc-macro2", + ":quote", + ":syn", + ], +) + +rust_binary( + name = "rustversion-buildscript", + srcs = glob(["vendor/rustversion-1.0.2/build/**"]), + crate_root = "vendor/rustversion-1.0.2/build/build.rs", +) + +genrule( + name = "rustversion-buildscript-run", + cmd = "OUT_DIR=${OUT} $(exe :rustversion-buildscript)", + type = "build.rs", + out = ".", +) + +rust_library( + name = "structopt", + srcs = glob(["vendor/structopt-0.3.9/src/**"]), + visibility = ["PUBLIC"], + deps = [ + ":clap", + ":lazy_static", + ":structopt-derive", + ], +) + +rust_library( + name = "structopt-derive", + srcs = glob(["vendor/structopt-derive-0.4.2/src/**"]), + proc_macro = True, + deps = [ + ":heck", + ":proc-macro-error", + ":proc-macro2", + ":quote", + ":syn", + ], +) + +rust_library( + name = "syn", + srcs = glob(["vendor/syn-1.0.14/src/**"]), + visibility = ["PUBLIC"], + features = [ + "clone-impls", + "derive", + "full", + "parsing", + "printing", + "proc-macro", + ], + deps = [ + ":proc-macro2", + ":quote", + ":unicode-xid", + ], +) + +rust_library( + name = "syn-mid", + srcs = glob(["vendor/syn-mid-0.5.0/src/**"]), + deps = [ + ":proc-macro2", + ":quote", + ":syn", + ], +) + +rust_library( + name = "termcolor", + srcs = glob(["vendor/termcolor-1.1.0/src/**"]), +) + +rust_library( + name = "textwrap", + srcs = glob(["vendor/textwrap-0.11.0/src/**"]), + deps = [":unicode-width"], +) + +rust_library( + name = "thiserror", + srcs = glob(["vendor/thiserror-1.0.11/src/**"]), + visibility = ["PUBLIC"], + deps = [":thiserror-impl"], +) + +rust_library( + name = "thiserror-impl", + srcs = glob(["vendor/thiserror-impl-1.0.11/src/**"]), + proc_macro = True, + deps = [ + ":proc-macro2", + ":quote", + ":syn", + ], +) + +rust_library( + name = "unicode-segmentation", + srcs = glob(["vendor/unicode-segmentation-1.6.0/src/**"]), + edition = "2015", +) + +rust_library( + name = "unicode-width", + srcs = glob(["vendor/unicode-width-0.1.7/src/**"]), +) + +rust_library( + name = "unicode-xid", + srcs = glob(["vendor/unicode-xid-0.2.0/src/**"]), +) diff --git a/third-party/Cargo.lock b/third-party/Cargo.lock new file mode 100644 index 00000000..fda20257 --- /dev/null +++ b/third-party/Cargo.lock @@ -0,0 +1,434 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "ansi_term" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7825f6833612eb2414095684fcf6c635becf3ce97fe48cf6421321e93bfbd53c" + +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "cc" +version = "1.0.50" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95e28fa049fda1c330bcf9d723be7663a899c4679724b34c81e9f5a326aab8cd" + +[[package]] +name = "clap" +version = "2.33.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5067f5bb2d80ef5d68b4c87db81601f0b75bca627bc2ef76b141d7b846a3c6d9" +dependencies = [ + "ansi_term", + "atty", + "bitflags", + "strsim", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "codespan" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21094c000d5db8035900662bbfddec754e79f795324254ac0817f36e5ccfc3f5" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "codespan-reporting" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "657b2c99e1f17bc3e5153808d9f704c8ba6171c3fe45e69fde26e2876156938b" +dependencies = [ + "codespan", + "termcolor", + "unicode-width", +] + +[[package]] +name = "cxx" +version = "0.1.2" +dependencies = [ + "anyhow", + "cc", + "codespan", + "codespan-reporting", + "cxxbridge-macro", + "link-cplusplus", + "proc-macro2", + "quote", + "rustversion", + "syn", + "thiserror", + "trybuild", +] + +[[package]] +name = "cxxbridge-cmd" +version = "0.1.2" +dependencies = [ + "anyhow", + "codespan", + "codespan-reporting", + "proc-macro2", + "quote", + "structopt", + "syn", + "thiserror", +] + +[[package]] +name = "cxxbridge-demo" +version = "0.0.0" +dependencies = [ + "cxx", +] + +[[package]] +name = "cxxbridge-macro" +version = "0.1.2" +dependencies = [ + "cxx", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "glob" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574" + +[[package]] +name = "heck" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "20564e78d53d2bb135c343b3f47714a56af2061f1c928fdb541dc7b9fdd94205" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2c55f143919fbc0bc77e427fe2d74cf23786d7c1875666f2fde3ac3c659bb67" +dependencies = [ + "libc", +] + +[[package]] +name = "itoa" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8b7a7c0c47db5545ed3fef7468ee7bb5b74691498139e4b3f6a20685dc6dd8e" + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.66" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d515b1f41455adea1313a4a2ac8a8a477634fbae63cc6100e3aebb207ce61558" + +[[package]] +name = "link-cplusplus" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "628cd9d7b5c99cb930617438a3d7896f5eb734647bc2838ded9ca50689507295" +dependencies = [ + "cc", +] + +[[package]] +name = "proc-macro-error" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "052b3c9af39c7e5e94245f820530487d19eb285faedcb40e0c3275132293f242" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "rustversion", + "syn", +] + +[[package]] +name = "proc-macro-error-attr" +version = "0.4.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d175bef481c7902e63e3165627123fff3502f06ac043d3ef42d08c1246da9253" +dependencies = [ + "proc-macro2", + "quote", + "rustversion", + "syn", + "syn-mid", +] + +[[package]] +name = "proc-macro2" +version = "1.0.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3acb317c6ff86a4e579dfa00fc5e6cca91ecbb4e7eb2df0468805b674eb88548" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "ryu" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bfa8506c1de11c9c4e4c38863ccbe02a305c8188e85a05a784c9e11e1c3910c8" + +[[package]] +name = "serde" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "414115f25f818d7dfccec8ee535d76949ae78584fc4f79a6f45a904bf8ab4449" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.104" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "128f9e303a5a29922045a830221b8f78ec74a5f544944f3d5984f8ec3895ef64" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9371ade75d4c2d6cb154141b9752cf3781ec9c05e0e5cf35060e1e70ee7b9c25" +dependencies = [ + "itoa", + "ryu", + "serde", +] + +[[package]] +name = "strsim" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" + +[[package]] +name = "structopt" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1bcbed7d48956fcbb5d80c6b95aedb553513de0a1b451ea92679d999c010e98" +dependencies = [ + "clap", + "lazy_static", + "structopt-derive", +] + +[[package]] +name = "structopt-derive" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "095064aa1f5b94d14e635d0a5684cf140c43ae40a0fd990708d38f5d669e5f64" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "af6f3550d8dff9ef7dc34d384ac6f107e5d31c8f57d9f28e0081503f547ac8f5" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "termcolor" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb6bfa289a4d7c5766392812c0a1f4c1ba45afa1ad47803c11e1f407d846d75f" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "thiserror" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee14bf8e6767ab4c687c9e8bc003879e042a96fd67a3ba5934eadb6536bef4db" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7b51e1fbc44b5a0840be594fbc0f960be09050f2617e61e6aa43bef97cd3ef4" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "toml" +version = "0.5.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffc92d160b1eef40665be3a05630d003936a3bc7da7421277846c2613e92c71a" +dependencies = [ + "serde", +] + +[[package]] +name = "trybuild" +version = "1.0.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f5b3f750c701725331ac78e389b5d143b7d25f6b6ffffd0d419759a9063ac5f" +dependencies = [ + "glob", + "lazy_static", + "serde", + "serde_json", + "termcolor", + "toml", +] + +[[package]] +name = "unicode-segmentation" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e83e153d1053cbb5a118eeff7fd5be06ed99153f00dbcd8ae310c5fb2b22edc0" + +[[package]] +name = "unicode-width" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "caaa9d531767d1ff2150b9332433f32a24622147e5ebb1f26409d5da67afd479" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "vec_map" +version = "0.8.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05c78687fb1a80548ae3250346c3db86a80a7cdd77bda190189f2d0a0987c81a" + +[[package]] +name = "winapi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8093091eeb260906a183e6ae1abdba2ef5ef2257a21801128899c3fc699229c6" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-util" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ccfbf554c6ad11084fb7517daca16cfdcaccbdadba4fc336f032a8b12c2ad80" +dependencies = [ + "winapi", +] + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" |