diff --git a/.github/workflows/pandoc.yml b/.github/workflows/pandoc.yml new file mode 100644 index 0000000..5db4df2 --- /dev/null +++ b/.github/workflows/pandoc.yml @@ -0,0 +1,82 @@ +name: Pandoc Action +on: [push,pull_request,workflow_dispatch] + +jobs: + # This workflow contains a single job called "build" + build: + # The type of runner that the job will run on + runs-on: ubuntu-latest + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v2 + + # Runs a single command using the runners shell + - name: Pandoc Document Converter pdf + uses: Ender-events/pandoc@master + with: + args: '--pdf-engine=xelatex --template=assets/templates/eisvogel.latex --highlight-style zenburn --toc -N --lua-filter _pandoc_filter/image_link.lua --lua-filter _pandoc_filter/add_title.lua -o assets/btcguide.pdf index_pandoc.md' + - name: Pandoc Document Converter epub + uses: Ender-events/pandoc@master + with: + args: '--css assets/templates/epub.css --toc -N --lua-filter _pandoc_filter/image_link.lua --lua-filter _pandoc_filter/add_title.lua -o assets/btcguide.epub index_pandoc.md' + - name: Install calibre + run: sudo apt-get update && sudo apt-get install calibre + - name: Convert epub to mobi + run: ebook-convert "assets/btcguide.epub" "assets/btcguide.mobi" --mobi-file-type new --pretty-print --mobi-keep-original-images + - name: Get current date + id: date + run: echo "::set-output name=date::$(date +'%Y-%m-%dT%H-%M')" + - name: Create tag + uses: actions/github-script@v3 + with: + github-token: ${{ github.token }} + script: | + github.git.createRef({ + owner: context.repo.owner, + repo: context.repo.repo, + ref: "refs/tags/${{ steps.date.outputs.date }}", + sha: context.sha + }) + - name: Create Release + id: create_release + uses: actions/create-release@v1.0.0 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.date.outputs.date }} + release_name: Release ${{ steps.date.outputs.date }} + draft: false + prerelease: false + - name: Upload Release Asset pdf + id: upload-release-asset-pdf + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./assets/btcguide.pdf + asset_name: btcguide.pdf + asset_content_type: application/pdf + - name: Upload Release Asset epub + id: upload-release-asset-epub + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./assets/btcguide.epub + asset_name: btcguide.epub + asset_content_type: application/epub + - name: Upload Release Asset mobi + id: upload-release-asset-mobi + uses: actions/upload-release-asset@v1.0.1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ./assets/btcguide.mobi + asset_name: btcguide.mobi + asset_content_type: application/mobi \ No newline at end of file diff --git a/.gitignore b/.gitignore index 726af56..6702d24 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,5 @@ dictionary.dic Gemfile.lock .DS_Store *.swp +tex2pdf*/* +assets/btcguide.* \ No newline at end of file diff --git a/.wordlist.txt b/.wordlist.txt index 405c9cf..45ec079 100644 --- a/.wordlist.txt +++ b/.wordlist.txt @@ -36,6 +36,7 @@ GBP Guillemet HODLer HODLers +Holger HW HWI HWIBridge @@ -58,6 +59,7 @@ Multisig Multisignature MyNode myNode +Nahrstaedt NDA Nodl Novak @@ -111,6 +113,7 @@ barcode bb bip bips +bitbox bitcoincore bitcoiners bitcoinonly @@ -133,6 +136,7 @@ coldcard coldcard's coldcardwallet colo +colorlinks conf config configurability @@ -146,6 +150,7 @@ disablewallet diy dmg dropdown +ebook electrum elsif endcomment @@ -153,6 +158,7 @@ endfor endif endunless english +epub exe explainer faf @@ -183,11 +189,13 @@ js json keepkey keyspace +lang li localhost lt macOS mainnet +markdownskip md meatspace merkle @@ -195,6 +203,7 @@ mflaxman microSD mins mitigations +mobi multicoin multisig multisig's @@ -203,6 +212,7 @@ nd notecards ol onsetup +pandoc pdf pendrive php @@ -246,6 +256,7 @@ stackoverflow stateful testnet th +titlepage tpub tradeoff tradeoffs @@ -257,6 +268,7 @@ udev ul unencrypted url +urlcolor usb useability utxo diff --git a/README.md b/README.md index bd3aac2..f3bba94 100644 --- a/README.md +++ b/README.md @@ -20,3 +20,23 @@ Spelling check passed :) Notes: * See `.wordlist.txt` for all the exception words. * `$ brew install aspell && pip install pyspelling` are needed. + + +## Create pdf/epub/mobi +1. Install [latex](https://www.latex-project.org/get/) +1. Install [pandoc](https://pandoc.org/installing.html) + + +1. Build the documents with + +``` +create_pdf.bat +create_ebook.bat +``` +or +``` +create_pdf.sh +create_ebook.sh +``` +1. The mobi file can be created from the epub file using [kindle previewer](https://www.amazon.com/gp/feature.html?ie=UTF8&docId=1003018611) + diff --git a/_pandoc_filter/add_title.lua b/_pandoc_filter/add_title.lua new file mode 100644 index 0000000..e819f8c --- /dev/null +++ b/_pandoc_filter/add_title.lua @@ -0,0 +1,317 @@ +function fix_path (path) + return '.' .. path +end + + +function skip_include(el) + + for i, item in ipairs(el) do + el[i] = pandoc.walk_block(item, { + Image = function (element) + element.src = fix_path(element.src) + return element + end + }) + + el[i] = pandoc.walk_block(el[i], { + Str = function (element) + if element.text:find('{:width',1) then + element.text = ("{width=") + end + return element + end + }) + + if item == nil or item.content == nil then + io.stderr:write(" ") + elseif item.content[1].t == nil then + io.stderr:write(" ") + elseif #item.content >= 1 and item.content[1].t == "Str" then + local str = item.content[1] + if str.text:find('{%%',1) then + io.stderr:write(" ") + el[i] = pandoc.Para(pandoc.Str("")) + elseif str.text:find('{:width',1) then + io.stderr:write(" ") + el[i] = pandoc.Para(pandoc.Str("")) + end + elseif #item.content == 1 and item.content[1].t == "Image" then + io.stderr:write(fix_path(item.content[1].src)) + el[i].content[1].src = fix_path(item.content[1].src) + end + end + return el +end + +function read_markdown(filename) + local f = io.open(filename, 'r') + local content = f:read('*a') + f:close() + return content +end + + +local function splitByPatternSeparator(str, sep, max) + sep = '^(.-)'..sep + local t,n,p, q,r,s = {},1,1, str:find(sep) + while q and n~=max do + t[n],n,p = s,n+1,r+1 + q,r,s = str:find(sep,p) + end + t[n] = str:sub(p) + return t +end + +function process_content(content, header_level) + local doc = pandoc.read(content) + + -- now we need to create a header from the metadata + local title=pandoc.utils.stringify(doc.meta.title) or nil + _, count = content:gsub("---\n", '') + if count >= 2 then + list = splitByPatternSeparator(content, "---\n", 3) + if title == nil then + content = list[3] + elseif header_level == 1 then + content = '# ' .. title .. '\n' .. list[3] + elseif header_level == 2 then + content = '## ' .. title .. '\n' .. list[3] + elseif header_level == 3 then + content = '### ' .. title .. '\n' .. list[3] + elseif header_level == 4 then + content = '#### ' .. title .. '\n' .. list[3] + end + doc = pandoc.read(content) + else + io.stderr:write("Warning: --- was not found twice at: " .. title .. "count: " .. count) + local newHeader=pandoc.Header(header_level, {pandoc.Str(title)}) + table.insert(doc.blocks, 1, newHeader) + end + return skip_include(doc.blocks) + +end + +function filter_content(content) + if string.find(content, '{%% include hw/psbt.md %%}', 1) ~= nil then + io.stderr:write("hw/psbt.md") + local new_content = read_markdown("./_includes/hw/psbt.md") + content = string.gsub(content, "{%% include hw/psbt.md %%}", new_content) + elseif string.find(content, '{%% include hw/wired_airgap.md %%}', 1) ~= nil then + io.stderr:write("hw/wired_airgap.md") + local new_content = read_markdown("./_includes/hw/wired_airgap.md") + content = string.gsub(content, "{%% include hw/wired_airgap.md %%}", new_content) + elseif string.find(content, '{%% include hw/udev.md %%}', 1) ~= nil then + io.stderr:write("hw/udev.md") + local new_content = read_markdown("./_includes/hw/udev.md") + content = string.gsub(content, "{%% include hw/udev.md %%}", new_content) + elseif string.find(content, '{%% include hw/u2f.md %%}', 1) ~= nil then + io.stderr:write("hw/u2f.md") + local new_content = read_markdown("./_includes/hw/u2f.md") + content = string.gsub(content, "{%% include hw/u2f.md %%}", new_content) + elseif string.find(content, '{%% include hw/stateless.md %%}', 1) ~= nil then + io.stderr:write("hw/stateless.md") + local new_content = read_markdown("./_includes/hw/stateless.md") + content = string.gsub(content, "{%% include hw/stateless.md %%}", new_content) + elseif string.find(content, '{%% include hw/shitcoins.md %%}', 1) ~= nil then + io.stderr:write("hw/shitcoins.md") + local new_content = read_markdown("./_includes/hw/shitcoins.md") + content = string.gsub(content, "{%% include hw/shitcoins.md %%}", new_content) + elseif string.find(content, '{%% include hw/python.md %%}', 1) ~= nil then + io.stderr:write("hw/python.md") + local new_content = read_markdown("./_includes/hw/python.md") + content = string.gsub(content, "{%% include hw/python.md %%}", new_content) + elseif string.find(content, '{%% include hw/experts.md %%}', 1) ~= nil then + io.stderr:write("hw/experts.md") + local new_content = read_markdown("./_includes/hw/experts.md") + content = string.gsub(content, "{%% include hw/experts.md %%}", new_content) + elseif string.find(content, '{%% include hw/closed_source.md %%}', 1) ~= nil then + io.stderr:write("hw/closed_source.md") + local new_content = read_markdown("./_includes/hw/closed_source.md") + content = string.gsub(content, "{%% include hw/closed_source.md %%}", new_content) + elseif string.find(content, '{%% include hw/encouragement.md %%}', 1) ~= nil then + io.stderr:write("hw/encouragement.md") + local new_content = read_markdown("./_includes/hw/encouragement.md") + new_content = string.gsub(new_content, "%%", "%%%%") + content = string.gsub(content, "{%% include hw/encouragement.md %%}", new_content) + elseif string.find(content, '{%% include hosted/utxo_privacy.md %%}', 1) ~= nil then + io.stderr:write("hosted/utxo_privacy.md") + local new_content = read_markdown("./_includes/hosted/utxo_privacy.md") + content = string.gsub(content, "{%% include hosted/utxo_privacy.md %%}", new_content) + elseif string.find(content, '{%% include hosted/spof.md %%}', 1) ~= nil then + io.stderr:write("hosted/spof.md") + local new_content = read_markdown("./_includes/hosted/spof.md") + content = string.gsub(content, "{%% include hosted/spof.md %%}", new_content) + elseif string.find(content, '{%% include hosted/limited_hw.md %%}', 1) ~= nil then + io.stderr:write("hosted/limited_hw.md") + local new_content = read_markdown("./_includes/hosted/limited_hw.md") + content = string.gsub(content, "{%% include hosted/limited_hw.md %%}", new_content) + elseif string.find(content, '{%% include hosted/limited_hw.md %%}', 1) ~= nil then + io.stderr:write("hosted/benefits.md") + local new_content = read_markdown("./_includes/hosted/benefits.md") + content = string.gsub(content, "{%% include hosted/benefits.md %%}", new_content) + end + + content = string.gsub(content, ":width", "width") + content = string.gsub(content, ' class="border_image"', '') + content = string.gsub(content, '{:class="border_image"}', '') + content = string.gsub(content, '%(./paper%)', '(#setup-paper-wallet)') + content = string.gsub(content, '%(paper%-advanced%)', '(#setup-paper-wallet-advanced)') + content = string.gsub(content, '%(/disclaimer%)', '(#disclaimer)') + content = string.gsub(content, '%(quorum%-advanced%)', '(#pick-quorum-advanced)') + content = string.gsub(content, '%(/quorum%-advanced%)', '(#pick-quorum-advanced)') + content = string.gsub(content, '%(/known%-issues/hw%-vendors%)', '(#hardware-wallet-vendors)') + content = string.gsub(content, '%(/known%-issues/multisig%)', '(#multisig)') + content = string.gsub(content, '%(/setup%-computer/%)', '(#setup-computer-overview)') + content = string.gsub(content, '%(setup%-computer/bitcoin%-node%)', '(#configure-bitcoin-node)') + content = string.gsub(content, '%(/setup%-computer/bitcoin%-node%)', '(#configure-bitcoin-node)') + content = string.gsub(content, '%(../setup%-computer/computer%)', '(#configure-computer)') + content = string.gsub(content, '%(../setup%-computer/computer%-advanced%)', '(#configure-computer-advanced)') + content = string.gsub(content, '%(/running%-bitcoin%)', '(#configure-bitcoin-node)') + content = string.gsub(content, '%(/known%-issues/verify%-receive%-address%)', '(#verifying-a-receive-address)') + content = string.gsub(content, '%(/known%-issues/verify%-receive%-address#confirm%-you%-can%-retrieve%-the%-key%)', '(#confirm-you-can-retrieve-the-key)') + content = string.gsub(content, '%(verify%-receive%-address/%)', '(#verify-receive-address)') + content = string.gsub(content, '%(/verify%-receive%-address/%)', '(#verify-receive-address)') + content = string.gsub(content, '%(/verify%-receive%-address%)', '(#verify-receive-address)') + content = string.gsub(content, '%(/verify%-receive%-address/advanced%)', '(#verify-receive-address-advanced)') + content = string.gsub(content, '%(verify%-receive%-address/advanced%)', '(#verify-receive-address-advanced)') + content = string.gsub(content, '%(/known%-issues/hardware/coldcard%)', '(#coldcard2)') + content = string.gsub(content, '%(/known%-issues/hardware/cobo%)', '(#cobo-vault)') + content = string.gsub(content, '%(/known%-issues/hardware/coldcard#verifying%-a%-receiving%-address%-breaks%-airgap%)', '(#verifying-a-receiving-address-breaks-airgap)') + content = string.gsub(content, '%(/backup%-wallet/public%-keys%)', '(#backup-public-keys)') + content = string.gsub(content, '%(/setup%-wallets/paper%)', '(#setup-paper-wallet)') + content = string.gsub(content, '%(setup%-wallets/paper%)', '(#setup-paper-wallet)') + content = string.gsub(content, '%(../setup%-wallets/paper%)', '(#setup-paper-wallet)') + content = string.gsub(content, '%(../setup%-wallets/cobo%)', '(#setup-cobo-vault)') + content = string.gsub(content, '%(setup%-wallets/paper#generate%-seed%)', '(#generate-seed)') + content = string.gsub(content, '%(computer%)', '(#configure-computer)') + content = string.gsub(content, '%(bitcoin%-node%)', '(#configure-bitcoin-node)') + content = string.gsub(content, '%(specter%)', '(#install-specter-desktop)') + content = string.gsub(content, '%(paper%)', '(#setup-paper-wallet)') + content = string.gsub(content, '%(cobo%)', '(#setup-cobo-vault)') + content = string.gsub(content, '%(coldcard%)', '(#setup-coldcard)') + content = string.gsub(content, '%(coordinate%-multisig%)', '(#coordinate-multisig)') + content = string.gsub(content, '%(/setup%-computer/specter%)', '(#install-specter-desktop)') + content = string.gsub(content, '%(../verify%-receive%-address/coldcard%)', '(#verify-receive-address-on-coldcard)') + content = string.gsub(content, '%(../verify%-receive%-address/cobo%)', '(#verify-receive-address-on-cobo-vault)') + content = string.gsub(content, '%(../verify%-receive%-address/specter%)', '(#verify-receive-address-with-specter-desktop)') + content = string.gsub(content, '%(/verify%-receive%-address/coldcard%)', '(#verify-receive-address-on-coldcard)') + content = string.gsub(content, '%(/verify%-receive%-address/coldcard%-advanced%)', '(#verify-receive-address-on-coldcard-advanced)') + content = string.gsub(content, '%(coldcard%-advanced%)', '(#verify-receive-address-on-coldcard-advanced)') + content = string.gsub(content, '%(/verify%-receive%-address/cobo%)', '(#verify-receive-address-on-cobo-vault)') + content = string.gsub(content, '%(/verify%-receive%-address/specter%)', '(#verify-receive-address-with-specter-desktop)') + content = string.gsub(content, '## Table of Contents', '') + content = string.gsub(content, '%(/known%-issues/seeds%-and%-privacy%)', '(#seeds-and-privacy)') + content = string.gsub(content, '%(/why%-multisig%-advanced#shamirs%-secret%-sharing%-scheme%)', '(#shamirs-secret-sharing-scheme)') + content = string.gsub(content, '%(/backup%-wallet/public%-keys%-advanced#extended%-public%-key%-info%)', '(#extended-public-key-info)') + content = string.gsub(content, '%(advanced%)', '(#emergency-recovery-advanced)') + content = string.gsub(content, '%(/known%-issues/hardware/trezor%)', '(#trezor)') + content = string.gsub(content, '%(/known%-issues/hardware/specter%-diy%)', '(#specter-diy2)') + content = string.gsub(content, '%(/known%-issues/hosted/unchained%)', '(#unchained-capital)') + content = string.gsub(content, '%(/known%-issues/hosted/casa%)', '(#casa)') + content = string.gsub(content, '%(/known%-issues/cost%)', '(#cost)') + content = string.gsub(content, '%(/known%-issues/complexity%)', '(#complexity)') + content = string.gsub(content, '%(/known%-issues/software/seedpicker%)', '(#seedpicker)') + content = string.gsub(content, '%(/backup%-wallet/seeds%)', '(#backup-seeds)') + content = string.gsub(content, '%(/setup%-wallets/%)', '(#setup-hardware-wallet-overview)') + content = string.gsub(content, '%(/setup%-wallets%)', '(#setup-hardware-wallet-overview)') + content = string.gsub(content, '%(/why%-multisig%)', '(#why-multisig)') + content = string.gsub(content, '%(/why%-multisig%-advanced%)', '(#why-multisig-advanced)') + content = string.gsub(content, '%(/assets/guide/bip39_wordlist.pdf%)', '(https://github.com/btcguide/btcguide.github.io/blob/master/assets/guide/bip39_wordlist.pdf)') + content = string.gsub(content, '%(/quorum%-advanced#3%-of%-5%-is%-excellent%)', '(#of-5-is-excellent)') + content = string.gsub(content, '%(advanced#redundant_address_verification%)', '(#verify-receive-address-advanced)') + content = string.gsub(content, '%(/backup%-wallet%)', '(#backup-wallet)') + content = string.gsub(content, '%(/backup%-wallet/seeds%)', '(#backup-seeds)') + content = string.gsub(content, '%(/backup%-wallet/public%-keys%)', '(#backup-public-keys)') + + return content +end + + + + +function Para(elem) + if #elem.content == 1 and elem.content[1].t == "Image" then + local img = elem.content[1] + if img.classes:find('markdown',1) then + local content =read_markdown(img.src) + content = filter_content(content) + return process_content(content, 1) + elseif img.classes:find('markdown_23',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n### ') + return process_content(content, 1) + elseif img.classes:find('markdown_42',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n#### ', '\n## ') + return process_content(content, 1) + elseif img.classes:find('markdown2',1) then + local content =read_markdown(img.src) + content = filter_content(content) + return process_content(content, 2) + elseif img.classes:find('markdown2_23',1) then + local content =read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n### ') + return process_content(content, 2) + elseif img.classes:find('markdown2_24',1) then + local content =read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n#### ') + return process_content(content, 2) + elseif img.classes:find('markdown2_43',1) then + local content =read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n#### ', '\n### ') + return process_content(content, 2) + elseif img.classes:find('markdown3',1) then + local content =read_markdown(img.src) + content = filter_content(content) + return process_content(content, 3) + elseif img.classes:find('markdown3_23',1) then + local content =read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n### ') + return process_content(content, 3) + elseif img.classes:find('markdown3_24',1) then + local content =read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n#### ') + return process_content(content, 3) + elseif img.classes:find('markdown4',1) then + local content =read_markdown(img.src) + content = filter_content(content) + return process_content(content, 4) + elseif img.classes:find('markdownskip',1) then + local content = read_markdown(img.src) + content = filter_content(content) + local doc = pandoc.read(content) + return skip_include(doc.blocks) + elseif img.classes:find('markdownskip_23',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n### ') + local doc = pandoc.read(content) + return skip_include(doc.blocks) + elseif img.classes:find('markdownskip_24',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n## ', '\n#### ') + local doc = pandoc.read(content) + return skip_include(doc.blocks) + elseif img.classes:find('markdownskip_34',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n### ', '\n#### ') + local doc = pandoc.read(content) + return skip_include(doc.blocks) + elseif img.classes:find('markdownskip_42',1) then + local content = read_markdown(img.src) + content = filter_content(content) + content = string.gsub(content, '\n#### ', '\n## ') + local doc = pandoc.read(content) + return skip_include(doc.blocks) + end + end +end \ No newline at end of file diff --git a/_pandoc_filter/image_link.lua b/_pandoc_filter/image_link.lua new file mode 100644 index 0000000..c07774e --- /dev/null +++ b/_pandoc_filter/image_link.lua @@ -0,0 +1,8 @@ +function fix_path (path) + return '.' .. path +end + +function Image (element) + element.src = fix_path(element.src) + return element +end \ No newline at end of file diff --git a/assets/templates/eisvogel.latex b/assets/templates/eisvogel.latex new file mode 100644 index 0000000..f79fa3f --- /dev/null +++ b/assets/templates/eisvogel.latex @@ -0,0 +1,1064 @@ +%% +% Copyright (c) 2017 - 2020, Pascal Wagler; +% Copyright (c) 2014 - 2020, John MacFarlane +% +% All rights reserved. +% +% Redistribution and use in source and binary forms, with or without +% modification, are permitted provided that the following conditions +% are met: +% +% - Redistributions of source code must retain the above copyright +% notice, this list of conditions and the following disclaimer. +% +% - 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. +% +% - Neither the name of John MacFarlane nor the names of other +% contributors may be used to endorse or promote products derived +% from this software without specific prior written permission. +% +% THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 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 +% COPYRIGHT OWNER 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. +%% + +%% +% This is the Eisvogel pandoc LaTeX template. +% +% For usage information and examples visit the official GitHub page: +% https://github.com/Wandmalfarbe/pandoc-latex-template +%% + +% Options for packages loaded elsewhere +\PassOptionsToPackage{unicode$for(hyperrefoptions)$,$hyperrefoptions$$endfor$}{hyperref} +\PassOptionsToPackage{hyphens}{url} +\PassOptionsToPackage{dvipsnames,svgnames*,x11names*,table}{xcolor} +$if(dir)$ +$if(latex-dir-rtl)$ +\PassOptionsToPackage{RTLdocument}{bidi} +$endif$ +$endif$ +$if(CJKmainfont)$ +\PassOptionsToPackage{space}{xeCJK} +$endif$ +% +\documentclass[ +$if(fontsize)$ + $fontsize$, +$endif$ +$if(lang)$ + $babel-lang$, +$endif$ +$if(papersize)$ + $papersize$paper, +$else$ + paper=a4, +$endif$ +$if(beamer)$ + ignorenonframetext, +$if(handout)$ + handout, +$endif$ +$if(aspectratio)$ + aspectratio=$aspectratio$, +$endif$ +$endif$ +$for(classoption)$ + $classoption$$sep$, +$endfor$ + ,captions=tableheading +]{$if(beamer)$$documentclass$$else$$if(book)$scrbook$else$scrartcl$endif$$endif$} +$if(beamer)$ +$if(background-image)$ +\usebackgroundtemplate{% + \includegraphics[width=\paperwidth]{$background-image$}% +} +$endif$ +\usepackage{pgfpages} +\setbeamertemplate{caption}[numbered] +\setbeamertemplate{caption label separator}{: } +\setbeamercolor{caption name}{fg=normal text.fg} +\beamertemplatenavigationsymbols$if(navigation)$$navigation$$else$empty$endif$ +$for(beameroption)$ +\setbeameroption{$beameroption$} +$endfor$ +% Prevent slide breaks in the middle of a paragraph +\widowpenalties 1 10000 +\raggedbottom +$if(section-titles)$ +\setbeamertemplate{part page}{ + \centering + \begin{beamercolorbox}[sep=16pt,center]{part title} + \usebeamerfont{part title}\insertpart\par + \end{beamercolorbox} +} +\setbeamertemplate{section page}{ + \centering + \begin{beamercolorbox}[sep=12pt,center]{part title} + \usebeamerfont{section title}\insertsection\par + \end{beamercolorbox} +} +\setbeamertemplate{subsection page}{ + \centering + \begin{beamercolorbox}[sep=8pt,center]{part title} + \usebeamerfont{subsection title}\insertsubsection\par + \end{beamercolorbox} +} +\AtBeginPart{ + \frame{\partpage} +} +\AtBeginSection{ + \ifbibliography + \else + \frame{\sectionpage} + \fi +} +\AtBeginSubsection{ + \frame{\subsectionpage} +} +$endif$ +$endif$ +$if(beamerarticle)$ +\usepackage{beamerarticle} % needs to be loaded first +$endif$ +\usepackage{amsmath,amssymb} +$if(fontfamily)$ +\usepackage[$for(fontfamilyoptions)$$fontfamilyoptions$$sep$,$endfor$]{$fontfamily$} +$else$ +\usepackage{lmodern} +$endif$ +$if(linestretch)$ +\usepackage{setspace} +\setstretch{$linestretch$} +$else$ +\usepackage{setspace} +\setstretch{1.2} +$endif$ +\usepackage{amsmath} +\usepackage{ifxetex,ifluatex} +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \usepackage[$if(fontenc)$$fontenc$$else$T1$endif$]{fontenc} + \usepackage[utf8]{inputenc} + \usepackage{textcomp} % provide euro and other symbols + \usepackage{amssymb} +\else % if luatex or xetex +$if(mathspec)$ + \ifxetex + \usepackage{amssymb} + \usepackage{mathspec} + \else + \usepackage{unicode-math} + \fi +$else$ + \usepackage{unicode-math} +$endif$ + \defaultfontfeatures{Scale=MatchLowercase} + \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1} +$if(mainfont)$ + \setmainfont[$for(mainfontoptions)$$mainfontoptions$$sep$,$endfor$]{$mainfont$} +$endif$ +$if(sansfont)$ + \setsansfont[$for(sansfontoptions)$$sansfontoptions$$sep$,$endfor$]{$sansfont$} +$endif$ +$if(monofont)$ + \setmonofont[$for(monofontoptions)$$monofontoptions$$sep$,$endfor$]{$monofont$} +$endif$ +$for(fontfamilies)$ + \newfontfamily{$fontfamilies.name$}[$for(fontfamilies.options)$$fontfamilies.options$$sep$,$endfor$]{$fontfamilies.font$} +$endfor$ +$if(mathfont)$ +$if(mathspec)$ + \ifxetex + \setmathfont(Digits,Latin,Greek)[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} + \else + \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} + \fi +$else$ + \setmathfont[$for(mathfontoptions)$$mathfontoptions$$sep$,$endfor$]{$mathfont$} +$endif$ +$endif$ +$if(CJKmainfont)$ + \ifxetex + \usepackage{xeCJK} + \setCJKmainfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + \fi +$endif$ +$if(luatexjapresetoptions)$ + \ifluatex + \usepackage[$for(luatexjapresetoptions)$$luatexjapresetoptions$$sep$,$endfor$]{luatexja-preset} + \fi +$endif$ +$if(CJKmainfont)$ + \ifluatex + \usepackage[$for(luatexjafontspecoptions)$$luatexjafontspecoptions$$sep$,$endfor$]{luatexja-fontspec} + \setmainjfont[$for(CJKoptions)$$CJKoptions$$sep$,$endfor$]{$CJKmainfont$} + \fi +$endif$ +\fi +$if(beamer)$ +$if(theme)$ +\usetheme[$for(themeoptions)$$themeoptions$$sep$,$endfor$]{$theme$} +$endif$ +$if(colortheme)$ +\usecolortheme{$colortheme$} +$endif$ +$if(fonttheme)$ +\usefonttheme{$fonttheme$} +$endif$ +$if(mainfont)$ +\usefonttheme{serif} % use mainfont rather than sansfont for slide text +$endif$ +$if(innertheme)$ +\useinnertheme{$innertheme$} +$endif$ +$if(outertheme)$ +\useoutertheme{$outertheme$} +$endif$ +$endif$ +% Use upquote if available, for straight quotes in verbatim environments +\IfFileExists{upquote.sty}{\usepackage{upquote}}{} +\IfFileExists{microtype.sty}{% use microtype if available + \usepackage[$for(microtypeoptions)$$microtypeoptions$$sep$,$endfor$]{microtype} + \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts +}{} +$if(indent)$ +$else$ +\makeatletter +\@ifundefined{KOMAClassName}{% if non-KOMA class + \IfFileExists{parskip.sty}{% + \usepackage{parskip} + }{% else + \setlength{\parindent}{0pt} + \setlength{\parskip}{6pt plus 2pt minus 1pt}} +}{% if KOMA class + \KOMAoptions{parskip=half}} +\makeatother +$endif$ +$if(verbatim-in-note)$ +\usepackage{fancyvrb} +$endif$ +\usepackage{xcolor} +\definecolor{default-linkcolor}{HTML}{A50000} +\definecolor{default-filecolor}{HTML}{A50000} +\definecolor{default-citecolor}{HTML}{4077C0} +\definecolor{default-urlcolor}{HTML}{4077C0} +\IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available +$if(footnotes-pretty)$ +% load footmisc in order to customize footnotes (footmisc has to be loaded before hyperref, cf. https://tex.stackexchange.com/a/169124/144087) +\usepackage[hang,flushmargin,bottom,multiple]{footmisc} +\setlength{\footnotemargin}{0.8em} % set space between footnote nr and text +\setlength{\footnotesep}{\baselineskip} % set space between multiple footnotes +\setlength{\skip\footins}{0.3cm} % set space between page content and footnote +\setlength{\footskip}{0.9cm} % set space between footnote and page bottom +$endif$ +\IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}} +\hypersetup{ +$if(title-meta)$ + pdftitle={$title-meta$}, +$endif$ +$if(author-meta)$ + pdfauthor={$author-meta$}, +$endif$ +$if(lang)$ + pdflang={$lang$}, +$endif$ +$if(subject)$ + pdfsubject={$subject$}, +$endif$ +$if(keywords)$ + pdfkeywords={$for(keywords)$$keywords$$sep$, $endfor$}, +$endif$ +$if(colorlinks)$ + colorlinks=true, + linkcolor=$if(linkcolor)$$linkcolor$$else$default-linkcolor$endif$, + filecolor=$if(filecolor)$$filecolor$$else$default-filecolor$endif$, + citecolor=$if(citecolor)$$citecolor$$else$default-citecolor$endif$, + urlcolor=$if(urlcolor)$$urlcolor$$else$default-urlcolor$endif$, +$else$ + hidelinks, +$endif$ + breaklinks=true, + pdfcreator={LaTeX via pandoc with the Eisvogel template}} +\urlstyle{same} % disable monospaced font for URLs +$if(verbatim-in-note)$ +\VerbatimFootnotes % allow verbatim text in footnotes +$endif$ +$if(geometry)$ +$if(beamer)$ +\geometry{$for(geometry)$$geometry$$sep$,$endfor$} +$else$ +\usepackage[$for(geometry)$$geometry$$sep$,$endfor$]{geometry} +$endif$ +$else$ +$if(beamer)$ +$else$ +\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering,$for(geometry)$$geometry$$sep$,$endfor$]{geometry} +$endif$ +$endif$ +$if(logo)$ +\usepackage[export]{adjustbox} +\usepackage{graphicx} +$endif$ +$if(beamer)$ +\newif\ifbibliography +$endif$ +$if(listings)$ +\usepackage{listings} +\newcommand{\passthrough}[1]{#1} +\lstset{defaultdialect=[5.3]Lua} +\lstset{defaultdialect=[x86masm]Assembler} +$endif$ +$if(listings-no-page-break)$ +\usepackage{etoolbox} +\BeforeBeginEnvironment{lstlisting}{\par\noindent\begin{minipage}{\linewidth}} +\AfterEndEnvironment{lstlisting}{\end{minipage}\par\addvspace{\topskip}} +$endif$ +$if(lhs)$ +\lstnewenvironment{code}{\lstset{language=Haskell,basicstyle=\small\ttfamily}}{} +$endif$ +$if(highlighting-macros)$ +$highlighting-macros$ + +% Workaround/bugfix from jannick0. +% See https://github.com/jgm/pandoc/issues/4302#issuecomment-360669013) +% or https://github.com/Wandmalfarbe/pandoc-latex-template/issues/2 +% +% Redefine the verbatim environment 'Highlighting' to break long lines (with +% the help of fvextra). Redefinition is necessary because it is unlikely that +% pandoc includes fvextra in the default template. +\usepackage{fvextra} +\DefineVerbatimEnvironment{Highlighting}{Verbatim}{breaklines,fontsize=$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$,commandchars=\\\{\}} + +$endif$ +$if(tables)$ +\usepackage{longtable,booktabs,array} +\usepackage{calc} % for calculating minipage widths +$if(beamer)$ +\usepackage{caption} +% Make caption package work with longtable +\makeatletter +\def\fnum@table{\tablename~\thetable} +\makeatother +$else$ +% Correct order of tables after \paragraph or \subparagraph +\usepackage{etoolbox} +\makeatletter +\patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{} +\makeatother +% Allow footnotes in longtable head/foot +\IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}} +\makesavenoteenv{longtable} +$endif$ +$endif$ +% add backlinks to footnote references, cf. https://tex.stackexchange.com/questions/302266/make-footnote-clickable-both-ways +$if(footnotes-disable-backlinks)$ +$else$ +\usepackage{footnotebackref} +$endif$ +$if(graphics)$ +\usepackage{graphicx} +\makeatletter +\def\maxwidth{\ifdim\Gin@nat@width>\linewidth\linewidth\else\Gin@nat@width\fi} +\def\maxheight{\ifdim\Gin@nat@height>\textheight\textheight\else\Gin@nat@height\fi} +\makeatother +% Scale images if necessary, so that they will not overflow the page +% margins by default, and it is still possible to overwrite the defaults +% using explicit options in \includegraphics[width, height, ...]{} +\setkeys{Gin}{width=\maxwidth,height=\maxheight,keepaspectratio} +% Set default figure placement to htbp +\makeatletter +\def\fps@figure{htbp} +\makeatother +$endif$ +$if(links-as-notes)$ +% Make links footnotes instead of hotlinks: +\DeclareRobustCommand{\href}[2]{#2\footnote{\url{#1}}} +$endif$ +$if(strikeout)$ +\usepackage[normalem]{ulem} +% Avoid problems with \sout in headers with hyperref +\pdfstringdefDisableCommands{\renewcommand{\sout}{}} +$endif$ +\setlength{\emergencystretch}{3em} % prevent overfull lines +\providecommand{\tightlist}{% + \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}} +$if(numbersections)$ +\setcounter{secnumdepth}{$if(secnumdepth)$$secnumdepth$$else$5$endif$} +$else$ +\setcounter{secnumdepth}{-\maxdimen} % remove section numbering +$endif$ +$if(beamer)$ +$else$ +$if(block-headings)$ +% Make \paragraph and \subparagraph free-standing +\ifx\paragraph\undefined\else + \let\oldparagraph\paragraph + \renewcommand{\paragraph}[1]{\oldparagraph{#1}\mbox{}} +\fi +\ifx\subparagraph\undefined\else + \let\oldsubparagraph\subparagraph + \renewcommand{\subparagraph}[1]{\oldsubparagraph{#1}\mbox{}} +\fi +$endif$ +$endif$ +$if(pagestyle)$ +\pagestyle{$pagestyle$} +$endif$ + +% Make use of float-package and set default placement for figures to H. +% The option H means 'PUT IT HERE' (as opposed to the standard h option which means 'You may put it here if you like'). +\usepackage{float} +\floatplacement{figure}{$if(float-placement-figure)$$float-placement-figure$$else$H$endif$} + +$for(header-includes)$ +$header-includes$ +$endfor$ +$if(lang)$ +\ifxetex + $if(mainfont)$ + $else$ + % See issue https://github.com/reutenauer/polyglossia/issues/127 + \renewcommand*\familydefault{\sfdefault} + $endif$ + % Load polyglossia as late as possible: uses bidi with RTL langages (e.g. Hebrew, Arabic) + \usepackage{polyglossia} + \setmainlanguage[$for(polyglossia-lang.options)$$polyglossia-lang.options$$sep$,$endfor$]{$polyglossia-lang.name$} +$for(polyglossia-otherlangs)$ + \setotherlanguage[$for(polyglossia-otherlangs.options)$$polyglossia-otherlangs.options$$sep$,$endfor$]{$polyglossia-otherlangs.name$} +$endfor$ +\else + \usepackage[$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=$babel-lang$]{babel} +% get rid of language-specific shorthands (see #6817): +\let\LanguageShortHands\languageshorthands +\def\languageshorthands#1{} +$if(babel-newcommands)$ + $babel-newcommands$ +$endif$ +\fi +$endif$ +\ifluatex + \usepackage{selnolig} % disable illegal ligatures +\fi +$if(dir)$ +\ifxetex + % Load bidi as late as possible as it modifies e.g. graphicx + \usepackage{bidi} +\fi +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \TeXXeTstate=1 + \newcommand{\RL}[1]{\beginR #1\endR} + \newcommand{\LR}[1]{\beginL #1\endL} + \newenvironment{RTL}{\beginR}{\endR} + \newenvironment{LTR}{\beginL}{\endL} +\fi +$endif$ +$if(natbib)$ +\usepackage[$natbiboptions$]{natbib} +\bibliographystyle{$if(biblio-style)$$biblio-style$$else$plainnat$endif$} +$endif$ +$if(biblatex)$ +\usepackage[$if(biblio-style)$style=$biblio-style$,$endif$$for(biblatexoptions)$$biblatexoptions$$sep$,$endfor$]{biblatex} +$for(bibliography)$ +\addbibresource{$bibliography$} +$endfor$ +$endif$ +$if(csl-refs)$ +\newlength{\cslhangindent} +\setlength{\cslhangindent}{1.5em} +\newlength{\csllabelwidth} +\setlength{\csllabelwidth}{3em} +\newenvironment{CSLReferences}[2] % #1 hanging-ident, #2 entry spacing + {% don't indent paragraphs + \setlength{\parindent}{0pt} + % turn on hanging indent if param 1 is 1 + \ifodd #1 \everypar{\setlength{\hangindent}{\cslhangindent}}\ignorespaces\fi + % set entry spacing + \ifnum #2 > 0 + \setlength{\parskip}{#2\baselineskip} + \fi + }% + {} +\usepackage{calc} +\newcommand{\CSLBlock}[1]{#1\hfill\break} +\newcommand{\CSLLeftMargin}[1]{\parbox[t]{\csllabelwidth}{#1}} +\newcommand{\CSLRightInline}[1]{\parbox[t]{\linewidth - \csllabelwidth}{#1}\break} +\newcommand{\CSLIndent}[1]{\hspace{\cslhangindent}#1} +$endif$ + +$if(title)$ +\title{$title$$if(thanks)$\thanks{$thanks$}$endif$} +$endif$ +$if(subtitle)$ +$if(beamer)$ +$else$ +\usepackage{etoolbox} +\makeatletter +\providecommand{\subtitle}[1]{% add subtitle to \maketitle + \apptocmd{\@title}{\par {\large #1 \par}}{}{} +} +\makeatother +$endif$ +\subtitle{$subtitle$} +$endif$ +\author{$for(author)$$author$$sep$ \and $endfor$} +\date{$date$} +$if(beamer)$ +$if(institute)$ +\institute{$for(institute)$$institute$$sep$ \and $endfor$} +$endif$ +$if(titlegraphic)$ +\titlegraphic{\includegraphics{$titlegraphic$}} +$endif$ +$if(logo)$ +\logo{\includegraphics{$logo$}} +$endif$ +$endif$ + + + +%% +%% added +%% + +% +% language specification +% +% If no language is specified, use English as the default main document language. +% +$if(lang)$$else$ +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + \usepackage[shorthands=off,$for(babel-otherlangs)$$babel-otherlangs$,$endfor$main=english]{babel} +$if(babel-newcommands)$ + $babel-newcommands$ +$endif$ +\else + $if(mainfont)$ + $else$ + % Workaround for bug in Polyglossia that breaks `\familydefault` when `\setmainlanguage` is used. + % See https://github.com/Wandmalfarbe/pandoc-latex-template/issues/8 + % See https://github.com/reutenauer/polyglossia/issues/186 + % See https://github.com/reutenauer/polyglossia/issues/127 + \renewcommand*\familydefault{\sfdefault} + $endif$ + % load polyglossia as late as possible as it *could* call bidi if RTL lang (e.g. Hebrew or Arabic) + \usepackage{polyglossia} + \setmainlanguage[]{english} +$for(polyglossia-otherlangs)$ + \setotherlanguage[$polyglossia-otherlangs.options$]{$polyglossia-otherlangs.name$} +$endfor$ +\fi +$endif$ + +$if(page-background)$ +\usepackage[pages=all]{background} +$endif$ + +% +% for the background color of the title page +% +$if(titlepage)$ +\usepackage{pagecolor} +\usepackage{afterpage} +$if(titlepage-background)$ +\usepackage{tikz} +$endif$ +$if(geometry)$ +$else$ +\usepackage[margin=2.5cm,includehead=true,includefoot=true,centering]{geometry} +$endif$ +$endif$ + +% +% break urls +% +\PassOptionsToPackage{hyphens}{url} + +% +% When using babel or polyglossia with biblatex, loading csquotes is recommended +% to ensure that quoted texts are typeset according to the rules of your main language. +% +\usepackage{csquotes} + +% +% captions +% +\definecolor{caption-color}{HTML}{777777} +$if(beamer)$ +$else$ +\usepackage[font={stretch=1.2}, textfont={color=caption-color}, position=top, skip=4mm, labelfont=bf, singlelinecheck=false, justification=$if(caption-justification)$$caption-justification$$else$raggedright$endif$]{caption} +\setcapindent{0em} +$endif$ + +% +% blockquote +% +\definecolor{blockquote-border}{RGB}{221,221,221} +\definecolor{blockquote-text}{RGB}{119,119,119} +\usepackage{mdframed} +\newmdenv[rightline=false,bottomline=false,topline=false,linewidth=3pt,linecolor=blockquote-border,skipabove=\parskip]{customblockquote} +\renewenvironment{quote}{\begin{customblockquote}\list{}{\rightmargin=0em\leftmargin=0em}% +\item\relax\color{blockquote-text}\ignorespaces}{\unskip\unskip\endlist\end{customblockquote}} + +% +% Source Sans Pro as the de­fault font fam­ily +% Source Code Pro for monospace text +% +% 'default' option sets the default +% font family to Source Sans Pro, not \sfdefault. +% +\ifnum 0\ifxetex 1\fi\ifluatex 1\fi=0 % if pdftex + $if(fontfamily)$ + $else$ + \usepackage[default]{sourcesanspro} + \usepackage{sourcecodepro} + $endif$ +\else % if not pdftex + $if(mainfont)$ + $else$ + \usepackage[default]{sourcesanspro} + \usepackage{sourcecodepro} + + % XeLaTeX specific adjustments for straight quotes: https://tex.stackexchange.com/a/354887 + % This issue is already fixed (see https://github.com/silkeh/latex-sourcecodepro/pull/5) but the + % fix is still unreleased. + % TODO: Remove this workaround when the new version of sourcecodepro is released on CTAN. + \ifxetex + \makeatletter + \defaultfontfeatures[\ttfamily] + { Numbers = \sourcecodepro@figurestyle, + Scale = \SourceCodePro@scale, + Extension = .otf } + \setmonofont + [ UprightFont = *-\sourcecodepro@regstyle, + ItalicFont = *-\sourcecodepro@regstyle It, + BoldFont = *-\sourcecodepro@boldstyle, + BoldItalicFont = *-\sourcecodepro@boldstyle It ] + {SourceCodePro} + \makeatother + \fi + $endif$ +\fi + +% +% heading color +% +\definecolor{heading-color}{RGB}{40,40,40} +$if(beamer)$ +$else$ +\addtokomafont{section}{\color{heading-color}} +$endif$ +% When using the classes report, scrreprt, book, +% scrbook or memoir, uncomment the following line. +%\addtokomafont{chapter}{\color{heading-color}} + +% +% variables for title, author and date +% +$if(beamer)$ +$else$ +\usepackage{titling} +\title{$title$} +\author{$for(author)$$author$$sep$, $endfor$} +\date{$date$} +$endif$ + +% +% tables +% +$if(tables)$ + +\definecolor{table-row-color}{HTML}{F5F5F5} +\definecolor{table-rule-color}{HTML}{999999} + +%\arrayrulecolor{black!40} +\arrayrulecolor{table-rule-color} % color of \toprule, \midrule, \bottomrule +\setlength\heavyrulewidth{0.3ex} % thickness of \toprule, \bottomrule +\renewcommand{\arraystretch}{1.3} % spacing (padding) + +$if(table-use-row-colors)$ +% TODO: This doesn't work anymore. I don't know why. +% Reset rownum counter so that each table +% starts with the same row colors. +% https://tex.stackexchange.com/questions/170637/restarting-rowcolors +% +% Unfortunately the colored cells extend beyond the edge of the +% table because pandoc uses @-expressions (@{}) like so: +% +% \begin{longtable}[]{@{}ll@{}} +% \end{longtable} +% +% https://en.wikibooks.org/wiki/LaTeX/Tables#.40-expressions +\let\oldlongtable\longtable +\let\endoldlongtable\endlongtable +\renewenvironment{longtable}{ +\rowcolors{3}{}{table-row-color!100} % row color +\oldlongtable} { +\endoldlongtable +\global\rownum=0\relax} +$endif$ +$endif$ + +% +% remove paragraph indention +% +\setlength{\parindent}{0pt} +\setlength{\parskip}{6pt plus 2pt minus 1pt} +\setlength{\emergencystretch}{3em} % prevent overfull lines + +% +% +% Listings +% +% + +$if(listings)$ + +% +% general listing colors +% +\definecolor{listing-background}{HTML}{F7F7F7} +\definecolor{listing-rule}{HTML}{B3B2B3} +\definecolor{listing-numbers}{HTML}{B3B2B3} +\definecolor{listing-text-color}{HTML}{000000} +\definecolor{listing-keyword}{HTML}{435489} +\definecolor{listing-keyword-2}{HTML}{1284CA} % additional keywords +\definecolor{listing-keyword-3}{HTML}{9137CB} % additional keywords +\definecolor{listing-identifier}{HTML}{435489} +\definecolor{listing-string}{HTML}{00999A} +\definecolor{listing-comment}{HTML}{8E8E8E} + +\lstdefinestyle{eisvogel_listing_style}{ + language = java, +$if(listings-disable-line-numbers)$ + xleftmargin = 0.6em, + framexleftmargin = 0.4em, +$else$ + numbers = left, + xleftmargin = 2.7em, + framexleftmargin = 2.5em, +$endif$ + backgroundcolor = \color{listing-background}, + basicstyle = \color{listing-text-color}\linespread{1.0}$if(code-block-font-size)$$code-block-font-size$$else$\small$endif$\ttfamily{}, + breaklines = true, + frame = single, + framesep = 0.19em, + rulecolor = \color{listing-rule}, + frameround = ffff, + tabsize = 4, + numberstyle = \color{listing-numbers}, + aboveskip = 1.0em, + belowskip = 0.1em, + abovecaptionskip = 0em, + belowcaptionskip = 1.0em, + keywordstyle = {\color{listing-keyword}\bfseries}, + keywordstyle = {[2]\color{listing-keyword-2}\bfseries}, + keywordstyle = {[3]\color{listing-keyword-3}\bfseries\itshape}, + sensitive = true, + identifierstyle = \color{listing-identifier}, + commentstyle = \color{listing-comment}, + stringstyle = \color{listing-string}, + showstringspaces = false, + escapeinside = {/*@}{@*/}, % Allow LaTeX inside these special comments + literate = + {á}{{\'a}}1 {é}{{\'e}}1 {í}{{\'i}}1 {ó}{{\'o}}1 {ú}{{\'u}}1 + {Á}{{\'A}}1 {É}{{\'E}}1 {Í}{{\'I}}1 {Ó}{{\'O}}1 {Ú}{{\'U}}1 + {à}{{\`a}}1 {è}{{\'e}}1 {ì}{{\`i}}1 {ò}{{\`o}}1 {ù}{{\`u}}1 + {À}{{\`A}}1 {È}{{\'E}}1 {Ì}{{\`I}}1 {Ò}{{\`O}}1 {Ù}{{\`U}}1 + {ä}{{\"a}}1 {ë}{{\"e}}1 {ï}{{\"i}}1 {ö}{{\"o}}1 {ü}{{\"u}}1 + {Ä}{{\"A}}1 {Ë}{{\"E}}1 {Ï}{{\"I}}1 {Ö}{{\"O}}1 {Ü}{{\"U}}1 + {â}{{\^a}}1 {ê}{{\^e}}1 {î}{{\^i}}1 {ô}{{\^o}}1 {û}{{\^u}}1 + {Â}{{\^A}}1 {Ê}{{\^E}}1 {Î}{{\^I}}1 {Ô}{{\^O}}1 {Û}{{\^U}}1 + {œ}{{\oe}}1 {Œ}{{\OE}}1 {æ}{{\ae}}1 {Æ}{{\AE}}1 {ß}{{\ss}}1 + {ç}{{\c c}}1 {Ç}{{\c C}}1 {ø}{{\o}}1 {å}{{\r a}}1 {Å}{{\r A}}1 + {€}{{\EUR}}1 {£}{{\pounds}}1 {«}{{\guillemotleft}}1 + {»}{{\guillemotright}}1 {ñ}{{\~n}}1 {Ñ}{{\~N}}1 {¿}{{?`}}1 + {…}{{\ldots}}1 {≥}{{>=}}1 {≤}{{<=}}1 {„}{{\glqq}}1 {“}{{\grqq}}1 + {”}{{''}}1 +} +\lstset{style=eisvogel_listing_style} + +% +% Java (Java SE 12, 2019-06-22) +% +\lstdefinelanguage{Java}{ + morekeywords={ + % normal keywords (without data types) + abstract,assert,break,case,catch,class,continue,default, + do,else,enum,exports,extends,final,finally,for,if,implements, + import,instanceof,interface,module,native,new,package,private, + protected,public,requires,return,static,strictfp,super,switch, + synchronized,this,throw,throws,transient,try,volatile,while, + % var is an identifier + var + }, + morekeywords={[2] % data types + % primitive data types + boolean,byte,char,double,float,int,long,short, + % String + String, + % primitive wrapper types + Boolean,Byte,Character,Double,Float,Integer,Long,Short + % number types + Number,AtomicInteger,AtomicLong,BigDecimal,BigInteger,DoubleAccumulator,DoubleAdder,LongAccumulator,LongAdder,Short, + % other + Object,Void,void + }, + morekeywords={[3] % literals + % reserved words for literal values + null,true,false, + }, + sensitive, + morecomment = [l]//, + morecomment = [s]{/*}{*/}, + morecomment = [s]{/**}{*/}, + morestring = [b]", + morestring = [b]', +} + +\lstdefinelanguage{XML}{ + morestring = [b]", + moredelim = [s][\bfseries\color{listing-keyword}]{<}{\ }, + moredelim = [s][\bfseries\color{listing-keyword}]{}, + moredelim = [l][\bfseries\color{listing-keyword}]{/>}, + moredelim = [l][\bfseries\color{listing-keyword}]{>}, + morecomment = [s]{}, + morecomment = [s]{}, + commentstyle = \color{listing-comment}, + stringstyle = \color{listing-string}, + identifierstyle = \color{listing-identifier} +} +$endif$ + +% +% header and footer +% +$if(beamer)$ +$else$ +$if(disable-header-and-footer)$ +$else$ +\usepackage{fancyhdr} + +\fancypagestyle{eisvogel-header-footer}{ + \fancyhead{} + \fancyfoot{} + \lhead[$if(header-right)$$header-right$$else$$date$$endif$]{$if(header-left)$$header-left$$else$$title$$endif$} + \chead[$if(header-center)$$header-center$$else$$endif$]{$if(header-center)$$header-center$$else$$endif$} + \rhead[$if(header-left)$$header-left$$else$$title$$endif$]{$if(header-right)$$header-right$$else$$date$$endif$} + \lfoot[$if(footer-right)$$footer-right$$else$\thepage$endif$]{$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$} + \cfoot[$if(footer-center)$$footer-center$$else$$endif$]{$if(footer-center)$$footer-center$$else$$endif$} + \rfoot[$if(footer-left)$$footer-left$$else$$for(author)$$author$$sep$, $endfor$$endif$]{$if(footer-right)$$footer-right$$else$\thepage$endif$} + \renewcommand{\headrulewidth}{0.4pt} + \renewcommand{\footrulewidth}{0.4pt} +} +\pagestyle{eisvogel-header-footer} +$if(page-background)$ +\backgroundsetup{ +scale=1, +color=black, +opacity=$if(page-background-opacity)$$page-background-opacity$$else$0.2$endif$, +angle=0, +contents={% + \includegraphics[width=\paperwidth,height=\paperheight]{$page-background$} + }% +} +$endif$ +$endif$ +$endif$ + +%% +%% end added +%% + +\begin{document} + +%% +%% begin titlepage +%% +$if(beamer)$ +$else$ +$if(titlepage)$ +\begin{titlepage} +$if(titlepage-background)$ +\newgeometry{top=2cm, right=4cm, bottom=3cm, left=4cm} +$else$ +\newgeometry{left=6cm} +$endif$ +$if(titlepage-color)$ +\definecolor{titlepage-color}{HTML}{$titlepage-color$} +\newpagecolor{titlepage-color}\afterpage{\restorepagecolor} +$endif$ +$if(titlepage-background)$ +\tikz[remember picture,overlay] \node[inner sep=0pt] at (current page.center){\includegraphics[width=\paperwidth,height=\paperheight]{$titlepage-background$}}; +$endif$ +\newcommand{\colorRule}[3][black]{\textcolor[HTML]{#1}{\rule{#2}{#3}}} +\begin{flushleft} +\noindent +\\[-1em] +\color[HTML]{$if(titlepage-text-color)$$titlepage-text-color$$else$5F5F5F$endif$} +\makebox[0pt][l]{\colorRule[$if(titlepage-rule-color)$$titlepage-rule-color$$else$435488$endif$]{1.3\textwidth}{$if(titlepage-rule-height)$$titlepage-rule-height$$else$4$endif$pt}} +\par +\noindent + +$if(titlepage-background)$ +% The titlepage with a background image has other text spacing and text size +{ + \setstretch{2} + \vfill + \vskip -8em + \noindent {\huge \textbf{\textsf{$title$}}} + $if(subtitle)$ + \vskip 1em + {\Large \textsf{$subtitle$}} + $endif$ + \vskip 2em + \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$} \vskip 0.6em \textsf{$date$}} + \vfill +} +$else$ +{ + \setstretch{1.4} + \vfill + \noindent {\huge \textbf{\textsf{$title$}}} + $if(subtitle)$ + \vskip 1em + {\Large \textsf{$subtitle$}} + $endif$ + \vskip 2em + \noindent {\Large \textsf{$for(author)$$author$$sep$, $endfor$}} + \vfill +} +$endif$ + +$if(logo)$ +\noindent +\includegraphics[width=$if(logo-width)$$logo-width$$else$100$endif$pt, left]{$logo$} +$endif$ + +$if(titlepage-background)$ +$else$ +\textsf{$date$} +$endif$ +\end{flushleft} +\end{titlepage} +\restoregeometry +$endif$ +$endif$ + +%% +%% end titlepage +%% + +$if(has-frontmatter)$ +\frontmatter +$endif$ +$if(title)$ +$if(beamer)$ +\frame{\titlepage} +$endif$ +$if(abstract)$ +\begin{abstract} +$abstract$ +\end{abstract} +$endif$ +$endif$ + +$if(first-chapter)$ +\setcounter{chapter}{$first-chapter$} +\addtocounter{chapter}{-1} +$endif$ + +$for(include-before)$ +$include-before$ + +$endfor$ +$if(toc)$ +$if(toc-title)$ +\renewcommand*\contentsname{$toc-title$} +$endif$ +$if(beamer)$ +\begin{frame}[allowframebreaks] +$if(toc-title)$ + \frametitle{$toc-title$} +$endif$ + \tableofcontents[hideallsubsections] +\end{frame} +$if(toc-own-page)$ +\newpage +$endif$ +$else$ +{ +$if(colorlinks)$ +\hypersetup{linkcolor=$if(toccolor)$$toccolor$$else$$endif$} +$endif$ +\setcounter{tocdepth}{$toc-depth$} +\tableofcontents +$if(toc-own-page)$ +\newpage +$endif$ +} +$endif$ +$endif$ +$if(lot)$ +\listoftables +$endif$ +$if(lof)$ +\listoffigures +$endif$ +$if(linestretch)$ +\setstretch{$linestretch$} +$endif$ +$if(has-frontmatter)$ +\mainmatter +$endif$ +$body$ + +$if(has-frontmatter)$ +\backmatter +$endif$ +$if(natbib)$ +$if(bibliography)$ +$if(biblio-title)$ +$if(has-chapters)$ +\renewcommand\bibname{$biblio-title$} +$else$ +\renewcommand\refname{$biblio-title$} +$endif$ +$endif$ +$if(beamer)$ +\begin{frame}[allowframebreaks]{$biblio-title$} + \bibliographytrue +$endif$ + \bibliography{$for(bibliography)$$bibliography$$sep$,$endfor$} +$if(beamer)$ +\end{frame} +$endif$ + +$endif$ +$endif$ +$if(biblatex)$ +$if(beamer)$ +\begin{frame}[allowframebreaks]{$biblio-title$} + \bibliographytrue + \printbibliography[heading=none] +\end{frame} +$else$ +\printbibliography$if(biblio-title)$[title=$biblio-title$]$endif$ +$endif$ + +$endif$ +$for(include-after)$ +$include-after$ + +$endfor$ +\end{document} diff --git a/assets/templates/epub.css b/assets/templates/epub.css new file mode 100644 index 0000000..58119b5 --- /dev/null +++ b/assets/templates/epub.css @@ -0,0 +1,55 @@ +/* This defines styles and classes used in the book */ +body { margin: 0; text-align: justify; font-size: medium; font-family: Athelas, Georgia, serif; } +code { font-family: monospace; } +h1 { text-align: left; } +h2 { text-align: left; } +h3 { text-align: left; } +h4 { text-align: left; } +h5 { text-align: left; } +h6 { text-align: left; } +h1.title { } +h2.author { } +h3.date { } +ol.toc { padding: 0; margin-left: 1em; } +ol.toc li { list-style-type: none; margin: 0; padding: 0; } + +/* Disable hyphenation for headings to avoid single-syllable-lines. +*/ +h1, +h2 { + -epub-hyphens: none; + -webkit-hyphens: none; + -moz-hyphens: none; + hyphens: none; +} + +/* Set the minimum amount of lines to show up on a separate page. (There is not much support for this at the moment.) +*/ +p, +blockquote { + orphans: 2; + widows: 2; +} + +/* Turn on hyphenation for paragraphs and captions only. +*/ +p, +figcaption { + -epub-hyphens: auto; + -webkit-hyphens: auto; + -moz-hyphens: auto; + hyphens: auto; +} + +/* Shortcodes for page-break rules. + Use data attributes to designate if and how the page should be broken before, inside or after an element. +*/ +h1, h2, h3, h4, h5, h6, +table, img, figure, video, +[data-page-break~=inside][data-page-break~=avoid] { page-break-inside: avoid; } +[data-page-break~=after] { page-break-after: always; } +h1, h2, h3, h4, h5, h6, +[data-page-break~=after][data-page-break~=avoid] { page-break-after: avoid; } +[data-page-break~=before] { page-break-before: always; } +[data-page-break~=before][data-page-break~=avoid] { page-break-before: avoid; } +img[data-page-break~=before] { page-break-before: left; } \ No newline at end of file diff --git a/contributors.md b/contributors.md index f98c851..642b2ad 100644 --- a/contributors.md +++ b/contributors.md @@ -8,12 +8,14 @@ title: Contributors #### Contributors * [Stephan Livera](https://twitter.com/stephanlivera) +* [Holger Nahrstaedt](https://github.com/holgern) #### Reviewers * TODO: add #### Wallet Manufacturers Thank you to all the hardware wallet developers who have sent me sample units, fixed bug reports and responded to feature requests. In particular: + * Coldcard: [Rodolfo Novak](https://twitter.com/nvk) & [Peter Gray](https://twitter.com/dochex) * Cobo Vault: [Lixin Liu](https://twitter.com/BitcoinLixin) & [Aaron Chen](https://github.com/aaronisme) * Trezor: [Pavol Rusnak](https://twitter.com/pavolrusnak) diff --git a/create_ebook.bat b/create_ebook.bat new file mode 100644 index 0000000..84830a0 --- /dev/null +++ b/create_ebook.bat @@ -0,0 +1 @@ +pandoc --css .\assets\templates\epub.css --toc -N --lua-filter _pandoc_filter\image_link.lua --lua-filter _pandoc_filter\add_title.lua -o assets\btcguide.epub index_pandoc.md diff --git a/create_ebook.sh b/create_ebook.sh new file mode 100644 index 0000000..2a37889 --- /dev/null +++ b/create_ebook.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pandoc --css assets/templates/epub.css --highlight-style zenburn --toc -N --lua-filter _pandoc_filter/image_link.lua --lua-filter _pandoc_filter/add_title.lua -o assets/btcguide.epub index_pandoc.md diff --git a/create_pdf.bat b/create_pdf.bat new file mode 100644 index 0000000..9657ce6 --- /dev/null +++ b/create_pdf.bat @@ -0,0 +1 @@ +pandoc --pdf-engine=xelatex --template=.\assets\templates\eisvogel.latex --highlight-style zenburn --toc -N --lua-filter _pandoc_filter\image_link.lua --lua-filter _pandoc_filter\add_title.lua -o assets\btcguide.pdf index_pandoc.md diff --git a/create_pdf.sh b/create_pdf.sh new file mode 100644 index 0000000..53d200a --- /dev/null +++ b/create_pdf.sh @@ -0,0 +1,2 @@ +#!/bin/bash +pandoc --pdf-engine=xelatex --template=assets/templates/eisvogel.latex --highlight-style zenburn --toc -N --lua-filter _pandoc_filter/image_link.lua --lua-filter _pandoc_filter/add_title.lua -o assets/btcguide.pdf index_pandoc.md \ No newline at end of file diff --git a/disclaimer.md b/disclaimer.md index 86fb539..96b0115 100644 --- a/disclaimer.md +++ b/disclaimer.md @@ -4,7 +4,7 @@ title: Disclaimer ### 1. Information published on btcguide.github.io - The website https://btcguide.github.io/ (hereinafter, referred to as the "Website") provides information and material of a general nature. You are not authorized and nor should you rely on the Website for legal advice, business advice, or advice of any kind. You act at your own risk in reliance on the contents of the Website. Should you make a decision to act or not act you should contact a licensed attorney in the relevant jurisdiction in which you want or need help. In no way are the owners of, or contributors to, the Website responsible for the actions, decisions, or other behavior taken or not taken by you in reliance upon the Website. + The website https://btcguide.github.io/ and all created documents from the same content (hereinafter, referred to as the "Website") provides information and material of a general nature. You are not authorized and nor should you rely on the Website for legal advice, business advice, or advice of any kind. You act at your own risk in reliance on the contents of the Website. Should you make a decision to act or not act you should contact a licensed attorney in the relevant jurisdiction in which you want or need help. In no way are the owners of, or contributors to, the Website responsible for the actions, decisions, or other behavior taken or not taken by you in reliance upon the Website. ### 2. Translations diff --git a/index_pandoc.md b/index_pandoc.md new file mode 100644 index 0000000..e88c5d0 --- /dev/null +++ b/index_pandoc.md @@ -0,0 +1,184 @@ +--- +title: 10x Security Bitcoin Guide +subtitle: How to store bitcoin without any single point of failure. +author: Michael Flaxman +lang: "en" +titlepage: true +urlcolor: blue +colorlinks: true +... + +# Preface + +## Purpose +Multisig security is a difference in kind and not in degree. It affords you the ability to avoid loss while making 1 (or more) catastrophic failures in securing your bitcoin. By using a security system that is fault-tolerant, you can move much faster (with less caution) through each step and still attain far higher levels of security vs any single-key system. This guide will show you how. + +The purpose of this guide is to make multisig accessible to a tech-savvy audience who does not write code. While it may be helpful if you are comfortable using the command line (especially for some of the optional advanced steps), it is not required. + +## Project Status +This guide is currently a work in progress. While the ultimate goal is for the process to be easy enough for non-technical users, there may be kinks to work out. Pull requests are welcome. + +![compensation file](/compensation.md){.markdown2} + +![contributors file](/contributors.md){.markdown2_43} + +![disclaimer file](/disclaimer.md){.markdown2} + +![why multisig file](/_pages/why-multisig.md){.markdown} + +## Why Multisig Advanced? + +![why-multisig-advanced file](/_pages/why-multisig-advanced.md){.markdownskip_34} + +![quorum file](/_pages/quorum.md){.markdown2} + +## Pick Quorum Advanced + +![quorum-advanced file](/_pages/quorum-advanced.md){.markdownskip_23} + +![equipment file](/_pages/equipment.md){.markdown2_23} + +![equipment-advanced file](/_pages/equipment-advanced.md){.markdownskip_23} + +![setup-computer1 file](/_pages/setup-computer/index.md){.markdown} + +![setup-computer2 file](/_pages/setup-computer/computer.md){.markdown2} + +### Configure Computer Advanced + +![setup-computer3 file](/_pages/setup-computer/computer-advanced.md){.markdownskip} + +![setup-computer4 file](/_pages/setup-computer/bitcoin-node.md){.markdown2} + +![setup-computer5 file](/_pages/setup-computer/bitcoin-node-advanced.md){.markdownskip_23} + +![setup-computer6 file](/_pages/setup-computer/specter.md){.markdown2} + +![setup-computer7 file](/_pages/setup-computer/specter-advanced.md){.markdownskip} + +![setup-wallets1 file](/_pages/setup-wallets/index.md){.markdown_42} + +![setup-wallets2 file](/_pages/setup-wallets/advanced.md){.markdownskip} + +![setup-wallets3 file](/_pages/setup-wallets/paper.md){.markdown2_23} + +## Setup Paper Wallet Advanced + +![setup-wallets4 file](/_pages/setup-wallets/paper-advanced.md){.markdownskip_24} + +![setup-wallets5 file](/_pages/setup-wallets/cobo.md){.markdown2_23} + +![setup-wallets6 file](/_pages/setup-wallets/cobo-advanced.md){.markdownskip_24} + +![setup-wallets7 file](/_pages/setup-wallets/coldcard.md){.markdown2_24} + +![setup-wallets8 file](/_pages/setup-wallets/coldcard-advanced.md){.markdownskip_24} + +![setup-wallets9 file](/_pages/setup-wallets/coordinate-multisig.md){.markdown2_24} + +![setup-wallets10 file](/_pages/setup-wallets/coordinate-multisig-advanced.md){.markdownskip_23} + +![verify-receive-address1 file](/_pages/verify-receive-address/index.md){.markdown} + +## Verify Receive Address Advanced + +![verify-receive-address2 file](/_pages/verify-receive-address/advanced.md){.markdownskip_23} + +![verify-receive-address3 file](/_pages/verify-receive-address/specter.md){.markdown2_23} + +![verify-receive-address4 file](/_pages/verify-receive-address/specter-advanced.md){.markdownskip_23} + +![verify-receive-address5 file](/_pages/verify-receive-address/cobo.md){.markdown2_23} + +![verify-receive-address6 file](/_pages/verify-receive-address/cobo-advanced.md){.markdownskip_23} + +![verify-receive-address7 file](/_pages/verify-receive-address/coldcard.md){.markdown2_23} + +## Verify Receive Address on Coldcard Advanced + +![verify-receive-address8 file](/_pages/verify-receive-address/coldcard-advanced.md){.markdownskip_24} + +![backup-wallet1 file](/_pages/backup-wallet/index.md){.markdown} + +![backup-wallet2 file](/_pages/backup-wallet/advanced.md){.markdownskip} + +![backup-wallet3 file](/_pages/backup-wallet/seeds.md){.markdown2} + +![backup-wallet4 file](/_pages/backup-wallet/seeds-advanced.md){.markdownskip} + +![backup-wallet5 file](/_pages/backup-wallet/public-keys.md){.markdown2} + +![backup-wallet6 file](/_pages/backup-wallet/public-keys-advanced.md){.markdownskip} + +![send-bitcoin1 file](/_pages/send-bitcoin/index.md){.markdown} + +![send-bitcoin2 file](/_pages/send-bitcoin/advanced.md){.markdownskip_42} + +![emergency-recovery1 file](/_pages/emergency-recovery/index.md){.markdown} + +## Emergency Recovery Advanced + +![emergency-recovery2 file](/_pages/emergency-recovery/advanced.md){.markdownskip} + +# Known Issues & Benefits + +## 10x Security Guide + +### Specter DIY {#specter-diy2} + +![known-issues1 file](/_pages/known-issues/software/specter.md){.markdownskip} + +### Coldcard {#coldcard2} + +![known-issues2 file](/_pages/known-issues/hardware/coldcard.md){.markdownskip} + +![known-issues3 file](/_pages/known-issues/hardware/cobo.md){.markdown3} + +![known-issues4 file](/_pages/known-issues/software/seedpicker.md){.markdown3} + +![known-issues5 file](/_pages/known-issues/multisig.md){.markdown3} + +![known-issues6 file](/_pages/known-issues/complexity.md){.markdown3_24} + +![known-issues7 file](/_pages/known-issues/hw-vendors.md){.markdown3} + +![known-issues8 file](/_pages/known-issues/verify-receive-address.md){.markdown3_23} + +![known-issues9 file](/_pages/known-issues/cost.md){.markdown3_24} + +![known-issues10 file](/_pages/known-issues/seeds-and-privacy.md){.markdown3} + +## Hosted Services + +![hosted1 file](/_pages/known-issues/hosted/casa.md){.markdown3} + +![hosted2 file](/_pages/known-issues/hosted/unchained.md){.markdown3} + +## Other Coordination Software + +![software1 file](/_pages/known-issues/software/electrum.md){.markdown3} + +![software2 file](/_pages/known-issues/software/caravan.md){.markdown3} + +![software3 file](/_pages/known-issues/software/sparrow.md){.markdown3} + +## Hardware Wallets + +![hardware1 file](/_pages/known-issues/hardware/specter-diy.md){.markdown3} + +![hardware2 file](/_pages/known-issues/hardware/trezor.md){.markdown3} + +![hardware3 file](/_pages/known-issues/hardware/ledger.md){.markdown3} + +![hardware4 file](/_pages/known-issues/hardware/keepkey.md){.markdown3} + +![hardware5 file](/_pages/known-issues/hardware/bitbox.md){.markdown3} + +## Other Protocols + +![protocols1 file](/_pages/known-issues/protocols/advanced-single-sig.md){.markdown3} + +![protocols1 file](/_pages/known-issues/protocols/glacier.md){.markdown3} + +![protocols1 file](/_pages/known-issues/protocols/yeti.md){.markdown3} +