]> Untitled Git - bdk-cli/commitdiff
Prep for publishing to crates.io, rename bin to bdk-cli
authorSteve Myers <steve@notmandatory.org>
Tue, 5 Jan 2021 20:54:21 +0000 (12:54 -0800)
committerSteve Myers <steve@notmandatory.org>
Thu, 7 Jan 2021 18:05:15 +0000 (10:05 -0800)
Cargo.toml
README.md
src/bdk_cli.rs [new file with mode: 0644]
src/lib.rs
src/repl.rs [deleted file]

index 110f73e237a5d8e87218222fa3972b6cd5dfe4c9..a49e43eaa996abf9f095141c10c4d836b96247ee 100644 (file)
@@ -2,7 +2,14 @@
 name = "bdk-cli"
 version = "0.1.0"
 edition = "2018"
-authors = ["Alekos Filini <alekos.filini@gmail.com>", "Riccardo Casatta <riccardo@casatta.it>"]
+authors = ["Alekos Filini <alekos.filini@gmail.com>", "Riccardo Casatta <riccardo@casatta.it>", "Steve Myers <steve@notmandatory.org"]
+homepage = "https://bitcoindevkit.org"
+repository = "https://github.com/bitcoindevkit/bdk-cli"
+documentation = "https://docs.rs/bdk-cli"
+description = "A CLI library and example CLI tool based on the BDK descriptor-based wallet library"
+keywords = ["bitcoin", "wallet", "descriptor", "psbt"]
+readme = "README.md"
+license-file = "LICENSE"
 
 [dependencies]
 bdk = { git = "https://github.com/bitcoindevkit/bdk.git" }
@@ -25,8 +32,7 @@ repl = ["async-trait", "rustyline", "dirs-next", "env_logger", "clap", "electrum
 electrum = ["bdk/electrum"]
 esplora = ["bdk/esplora"]
 
-
 [[bin]]
-name = "repl"
-path = "src/repl.rs"
+name = "bdk-cli"
+path = "src/bdk_cli.rs"
 required-features = ["repl"]
\ No newline at end of file
index f31b727bf7f05f4674477206fdad260253bcc243..d698abf3b798474c9e21f8fdb44fb2619bf211b3 100644 (file)
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-# BDK CLI lib and REPL bin
+# bdk-cli lib and example bin tool
 
 ![CI](https://github.com/bitcoindevkit/bdk-cli/workflows/CI/badge.svg)
 ![Code Coverage](https://github.com/bitcoindevkit/bdk-cli/workflows/Code%20Coverage/badge.svg)
@@ -8,10 +8,10 @@
 This project provides a command line interface (cli) Bitcoin wallet library and [`REPL`](https://en.wikipedia.org/wiki/Read%E2%80%93eval%E2%80%93print_loop)
 wallet tool based on the [bdk](https://github.com/bitcoindevkit/bdk) library.
 
-### REPL wallet usage examples
+### bdk-cli bin usage examples
 
-To get usage information for the `repl` wallet tool use the below command which
-returns a list of available wallet options and commands:
+To get usage information for the `bdk-cli` bin use the below command which returns a list of
+available wallet options and commands:
 
 ```shell
 cargo run
diff --git a/src/bdk_cli.rs b/src/bdk_cli.rs
new file mode 100644 (file)
index 0000000..c7b1c16
--- /dev/null
@@ -0,0 +1,172 @@
+// Magical Bitcoin Library
+// Written in 2020 by
+//     Alekos Filini <alekos.filini@gmail.com>
+//
+// Copyright (c) 2020 Magical Bitcoin
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+use std::fs;
+use std::path::PathBuf;
+use std::sync::Arc;
+
+use bitcoin::Network;
+use clap::AppSettings;
+use log::{debug, info, warn};
+use rustyline::error::ReadlineError;
+use rustyline::Editor;
+use structopt::StructOpt;
+
+use bdk::bitcoin;
+#[cfg(feature = "esplora")]
+use bdk::blockchain::esplora::EsploraBlockchainConfig;
+use bdk::blockchain::{
+    AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain, ElectrumBlockchainConfig,
+};
+use bdk::sled;
+use bdk::Wallet;
+use bdk_cli::{self, WalletOpt, WalletSubCommand};
+
+#[derive(Debug, StructOpt, Clone, PartialEq)]
+#[structopt(name = "BDK CLI", setting = AppSettings::NoBinaryName,
+version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
+author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
+struct ReplOpt {
+    /// Wallet sub-command
+    #[structopt(subcommand)]
+    pub subcommand: WalletSubCommand,
+}
+
+fn prepare_home_dir() -> PathBuf {
+    let mut dir = PathBuf::new();
+    dir.push(&dirs_next::home_dir().unwrap());
+    dir.push(".bdk-bitcoin");
+
+    if !dir.exists() {
+        info!("Creating home directory {}", dir.as_path().display());
+        fs::create_dir(&dir).unwrap();
+    }
+
+    dir.push("database.sled");
+    dir
+}
+
+fn main() {
+    env_logger::init();
+
+    let cli_opt: WalletOpt = WalletOpt::from_args();
+
+    let network = cli_opt.network;
+    debug!("network: {:?}", network);
+    if network == Network::Bitcoin {
+        warn!("This is experimental software and not currently recommended for use on Bitcoin mainnet, proceed with caution.")
+    }
+
+    let descriptor = cli_opt.descriptor.as_str();
+    let change_descriptor = cli_opt.change_descriptor.as_deref();
+    debug!("descriptors: {:?} {:?}", descriptor, change_descriptor);
+
+    let database = sled::open(prepare_home_dir().to_str().unwrap()).unwrap();
+    let tree = database.open_tree(cli_opt.wallet).unwrap();
+    debug!("database opened successfully");
+
+    // Try to use Esplora config if "esplora" feature is enabled
+    #[cfg(feature = "esplora")]
+    let config_esplora: Option<AnyBlockchainConfig> = {
+        let esplora_concurrency = cli_opt.esplora_concurrency;
+        cli_opt.esplora.map(|base_url| {
+            AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
+                base_url,
+                concurrency: Some(esplora_concurrency),
+            })
+        })
+    };
+    #[cfg(not(feature = "esplora"))]
+    let config_esplora = None;
+
+    // Fall back to Electrum config if Esplora config isn't provided
+    let config =
+        config_esplora.unwrap_or(AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
+            url: cli_opt.electrum,
+            socks5: cli_opt.proxy,
+            retry: 10,
+            timeout: 10,
+        }));
+
+    let wallet = Wallet::new(
+        descriptor,
+        change_descriptor,
+        network,
+        tree,
+        AnyBlockchain::from_config(&config).unwrap(),
+    )
+    .unwrap();
+
+    let wallet = Arc::new(wallet);
+
+    match cli_opt.subcommand {
+        WalletSubCommand::Repl => {
+            let mut rl = Editor::<()>::new();
+
+            // if rl.load_history("history.txt").is_err() {
+            //     println!("No previous history.");
+            // }
+
+            loop {
+                let readline = rl.readline(">> ");
+                match readline {
+                    Ok(line) => {
+                        if line.trim() == "" {
+                            continue;
+                        }
+                        rl.add_history_entry(line.as_str());
+                        let split_line: Vec<&str> = line.split(' ').collect();
+                        let repl_subcommand: Result<ReplOpt, clap::Error> =
+                            ReplOpt::from_iter_safe(split_line);
+                        debug!("repl_subcommand = {:?}", repl_subcommand);
+
+                        if let Err(err) = repl_subcommand {
+                            println!("{}", err.message);
+                            continue;
+                        }
+
+                        let result = bdk_cli::handle_wallet_subcommand(
+                            &Arc::clone(&wallet),
+                            repl_subcommand.unwrap().subcommand,
+                        )
+                        .unwrap();
+                        println!("{}", serde_json::to_string_pretty(&result).unwrap());
+                    }
+                    Err(ReadlineError::Interrupted) => continue,
+                    Err(ReadlineError::Eof) => break,
+                    Err(err) => {
+                        println!("{:?}", err);
+                        break;
+                    }
+                }
+            }
+
+            // rl.save_history("history.txt").unwrap();
+        }
+        _ => {
+            let result = bdk_cli::handle_wallet_subcommand(&wallet, cli_opt.subcommand).unwrap();
+            println!("{}", serde_json::to_string_pretty(&result).unwrap());
+        }
+    }
+}
index d5ec993f8fbebdc3c44670b3823b961fea5adbe6..d10517614acacea4c99297fe348d2c5cad4f5622 100644 (file)
@@ -28,7 +28,7 @@
 //! parse global wallet options and wallet subcommand options needed for a wallet command line
 //! interface.
 //!
-//! See the `repl.rs` example for how to use this module to create a simple command line REPL
+//! See the `bdk-cli` example bin for how to use this module to create a simple command line
 //! wallet application.
 //!
 //! See [`WalletOpt`] for global wallet options and [`WalletSubCommand`] for supported sub-commands.
@@ -50,7 +50,7 @@
 //! // to get args from cli use:
 //! // let cli_opt = WalletOpt::from_args();
 //!
-//! let cli_args = vec!["repl", "--network", "testnet", "--descriptor",
+//! let cli_args = vec!["bdk-cli", "--network", "testnet", "--descriptor",
 //!                     "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/*)",
 //!                     "sync", "--max_addresses", "50"];
 //! let cli_opt = WalletOpt::from_iter(&cli_args);
@@ -124,7 +124,7 @@ use bdk::{FeeRate, KeychainKind, TxBuilder, Wallet};
 /// # use structopt::StructOpt;
 /// # use bdk_cli::{WalletSubCommand, WalletOpt};
 ///
-/// let cli_args = vec!["repl", "--network", "testnet",
+/// let cli_args = vec!["bdk-cli", "--network", "testnet",
 ///                     "--descriptor", "wpkh(tpubEBr4i6yk5nf5DAaJpsi9N2pPYBeJ7fZ5Z9rmN4977iYLCGco1VyjB9tvvuvYtfZzjD5A8igzgw3HeWeeKFmanHYqksqZXYXGsw5zjnj7KM9/44'/1'/0'/0/*)",
 ///                     "sync", "--max_addresses", "50"];
 ///
@@ -153,7 +153,7 @@ use bdk::{FeeRate, KeychainKind, TxBuilder, Wallet};
 /// ```
 
 #[derive(Debug, StructOpt, Clone, PartialEq)]
-#[structopt(name = "BDK Wallet",
+#[structopt(name = "BDK CLI",
 version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
 author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
 pub struct WalletOpt {
@@ -212,8 +212,8 @@ pub struct WalletOpt {
 /// Wallet sub-command
 ///
 /// A [structopt](https://docs.rs/crate/structopt) enum that parses wallet sub-command arguments from
-/// the command line or from a `String` vector, such as in the [`repl`](https://github.com/bitcoindevkit/bdk/blob/master/examples/repl.rs)
-/// example app.
+/// the command line or from a `String` vector, such as in the [`bdk-cli`](https://github.com/bitcoindevkit/bdk-cli/blob/master/src/bdkcli.rs)
+/// example cli wallet.
 ///
 /// # Example
 ///
@@ -221,7 +221,7 @@ pub struct WalletOpt {
 /// # use bdk_cli::WalletSubCommand;
 /// # use structopt::StructOpt;
 ///
-/// let sync_sub_command = WalletSubCommand::from_iter(&["repl", "sync", "--max_addresses", "50"]);
+/// let sync_sub_command = WalletSubCommand::from_iter(&["bdk-cli", "sync", "--max_addresses", "50"]);
 /// assert!(matches!(
 ///     sync_sub_command,
 ///     WalletSubCommand::Sync {
@@ -232,7 +232,7 @@ pub struct WalletOpt {
 ///
 /// To capture wallet sub-commands from a string vector without a preceeding binary name you can
 /// create a custom struct the includes the `NoBinaryName` clap setting and wraps the WalletSubCommand
-/// enum. See also the [`repl`](https://github.com/bitcoindevkit/bdk/blob/master/examples/repl.rs)
+/// enum. See also the [`bdk-cli`](https://github.com/bitcoindevkit/bdk-cli/blob/master/src/bdkcli.rs)
 /// example app.
 ///
 /// # Example
@@ -242,7 +242,7 @@ pub struct WalletOpt {
 /// # use clap::AppSettings;
 ///
 /// #[derive(Debug, StructOpt, Clone, PartialEq)]
-/// #[structopt(name = "BDK Wallet", setting = AppSettings::NoBinaryName,
+/// #[structopt(name = "BDK CLI", setting = AppSettings::NoBinaryName,
 /// version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
 /// author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
 /// struct ReplOpt {
@@ -597,7 +597,7 @@ mod test {
 
     #[test]
     fn test_get_new_address() {
-        let cli_args = vec!["repl", "--network", "bitcoin",
+        let cli_args = vec!["bdk-cli", "--network", "bitcoin",
                             "--descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
                             "--change_descriptor", "wpkh(xpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
                             "--esplora", "https://blockstream.info/api/",
@@ -625,7 +625,7 @@ mod test {
 
     #[test]
     fn test_sync() {
-        let cli_args = vec!["repl", "--network", "testnet",
+        let cli_args = vec!["bdk-cli", "--network", "testnet",
                             "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
                             "sync", "--max_addresses", "50"];
 
@@ -652,7 +652,7 @@ mod test {
 
     #[test]
     fn test_create_tx() {
-        let cli_args = vec!["repl", "--network", "testnet", "--proxy", "127.0.0.1:9150",
+        let cli_args = vec!["bdk-cli", "--network", "testnet", "--proxy", "127.0.0.1:9150",
                             "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
                             "--change_descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/1/*)",
                             "--server","ssl://electrum.blockstream.info:50002",
@@ -706,7 +706,7 @@ mod test {
 
     #[test]
     fn test_broadcast() {
-        let cli_args = vec!["repl", "--network", "testnet",
+        let cli_args = vec!["bdk-cli", "--network", "testnet",
                             "--descriptor", "wpkh(tpubDEnoLuPdBep9bzw5LoGYpsxUQYheRQ9gcgrJhJEcdKFB9cWQRyYmkCyRoTqeD4tJYiVVgt6A3rN6rWn9RYhR9sBsGxji29LYWHuKKbdb1ev/0/*)",
                             "broadcast",
                             "--psbt", "cHNidP8BAEICAAAAASWhGE1AhvtO+2GjJHopssFmgfbq+WweHd8zN/DeaqmDAAAAAAD/////AQAAAAAAAAAABmoEAAECAwAAAAAAAAA="];
diff --git a/src/repl.rs b/src/repl.rs
deleted file mode 100644 (file)
index 17b6cad..0000000
+++ /dev/null
@@ -1,172 +0,0 @@
-// Magical Bitcoin Library
-// Written in 2020 by
-//     Alekos Filini <alekos.filini@gmail.com>
-//
-// Copyright (c) 2020 Magical Bitcoin
-//
-// Permission is hereby granted, free of charge, to any person obtaining a copy
-// of this software and associated documentation files (the "Software"), to deal
-// in the Software without restriction, including without limitation the rights
-// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-// copies of the Software, and to permit persons to whom the Software is
-// furnished to do so, subject to the following conditions:
-//
-// The above copyright notice and this permission notice shall be included in all
-// copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-// SOFTWARE.
-
-use std::fs;
-use std::path::PathBuf;
-use std::sync::Arc;
-
-use bitcoin::Network;
-use clap::AppSettings;
-use log::{debug, info, warn};
-use rustyline::error::ReadlineError;
-use rustyline::Editor;
-use structopt::StructOpt;
-
-use bdk::bitcoin;
-#[cfg(feature = "esplora")]
-use bdk::blockchain::esplora::EsploraBlockchainConfig;
-use bdk::blockchain::{
-    AnyBlockchain, AnyBlockchainConfig, ConfigurableBlockchain, ElectrumBlockchainConfig,
-};
-use bdk::sled;
-use bdk::Wallet;
-use bdk_cli::{self, WalletOpt, WalletSubCommand};
-
-#[derive(Debug, StructOpt, Clone, PartialEq)]
-#[structopt(name = "BDK Wallet", setting = AppSettings::NoBinaryName,
-version = option_env ! ("CARGO_PKG_VERSION").unwrap_or("unknown"),
-author = option_env ! ("CARGO_PKG_AUTHORS").unwrap_or(""))]
-struct ReplOpt {
-    /// Wallet sub-command
-    #[structopt(subcommand)]
-    pub subcommand: WalletSubCommand,
-}
-
-fn prepare_home_dir() -> PathBuf {
-    let mut dir = PathBuf::new();
-    dir.push(&dirs_next::home_dir().unwrap());
-    dir.push(".bdk-bitcoin");
-
-    if !dir.exists() {
-        info!("Creating home directory {}", dir.as_path().display());
-        fs::create_dir(&dir).unwrap();
-    }
-
-    dir.push("database.sled");
-    dir
-}
-
-fn main() {
-    env_logger::init();
-
-    let cli_opt: WalletOpt = WalletOpt::from_args();
-
-    let network = cli_opt.network;
-    debug!("network: {:?}", network);
-    if network == Network::Bitcoin {
-        warn!("This is experimental software and not currently recommended for use on Bitcoin mainnet, proceed with caution.")
-    }
-
-    let descriptor = cli_opt.descriptor.as_str();
-    let change_descriptor = cli_opt.change_descriptor.as_deref();
-    debug!("descriptors: {:?} {:?}", descriptor, change_descriptor);
-
-    let database = sled::open(prepare_home_dir().to_str().unwrap()).unwrap();
-    let tree = database.open_tree(cli_opt.wallet).unwrap();
-    debug!("database opened successfully");
-
-    // Try to use Esplora config if "esplora" feature is enabled
-    #[cfg(feature = "esplora")]
-    let config_esplora: Option<AnyBlockchainConfig> = {
-        let esplora_concurrency = cli_opt.esplora_concurrency;
-        cli_opt.esplora.map(|base_url| {
-            AnyBlockchainConfig::Esplora(EsploraBlockchainConfig {
-                base_url,
-                concurrency: Some(esplora_concurrency),
-            })
-        })
-    };
-    #[cfg(not(feature = "esplora"))]
-    let config_esplora = None;
-
-    // Fall back to Electrum config if Esplora config isn't provided
-    let config =
-        config_esplora.unwrap_or(AnyBlockchainConfig::Electrum(ElectrumBlockchainConfig {
-            url: cli_opt.electrum,
-            socks5: cli_opt.proxy,
-            retry: 10,
-            timeout: 10,
-        }));
-
-    let wallet = Wallet::new(
-        descriptor,
-        change_descriptor,
-        network,
-        tree,
-        AnyBlockchain::from_config(&config).unwrap(),
-    )
-    .unwrap();
-
-    let wallet = Arc::new(wallet);
-
-    match cli_opt.subcommand {
-        WalletSubCommand::Repl => {
-            let mut rl = Editor::<()>::new();
-
-            // if rl.load_history("history.txt").is_err() {
-            //     println!("No previous history.");
-            // }
-
-            loop {
-                let readline = rl.readline(">> ");
-                match readline {
-                    Ok(line) => {
-                        if line.trim() == "" {
-                            continue;
-                        }
-                        rl.add_history_entry(line.as_str());
-                        let split_line: Vec<&str> = line.split(' ').collect();
-                        let repl_subcommand: Result<ReplOpt, clap::Error> =
-                            ReplOpt::from_iter_safe(split_line);
-                        debug!("repl_subcommand = {:?}", repl_subcommand);
-
-                        if let Err(err) = repl_subcommand {
-                            println!("{}", err.message);
-                            continue;
-                        }
-
-                        let result = bdk_cli::handle_wallet_subcommand(
-                            &Arc::clone(&wallet),
-                            repl_subcommand.unwrap().subcommand,
-                        )
-                        .unwrap();
-                        println!("{}", serde_json::to_string_pretty(&result).unwrap());
-                    }
-                    Err(ReadlineError::Interrupted) => continue,
-                    Err(ReadlineError::Eof) => break,
-                    Err(err) => {
-                        println!("{:?}", err);
-                        break;
-                    }
-                }
-            }
-
-            // rl.save_history("history.txt").unwrap();
-        }
-        _ => {
-            let result = bdk_cli::handle_wallet_subcommand(&wallet, cli_opt.subcommand).unwrap();
-            println!("{}", serde_json::to_string_pretty(&result).unwrap());
-        }
-    }
-}