Compare commits
9 Commits
cc0a7d446d
...
push-zxunx
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2417959fbd | ||
|
|
4e338bc1d4 | ||
|
|
053d2e28cb | ||
|
|
30b7175702 | ||
|
|
35d275c104 | ||
|
|
78156a8c95 | ||
|
|
0eae496a94 | ||
|
|
d49592c5d4 | ||
|
|
1d0db893f1 |
13
.gitignore
vendored
@@ -3,6 +3,17 @@
|
||||
/jupyterhub_volumes/shared
|
||||
/jupyterhub_volumes/jupyterhub
|
||||
/jupyterhub_volumes/caddy
|
||||
/jupyterhub_volumes/course/data/Genbank
|
||||
/jupyterhub_volumes/web/
|
||||
/**/.DS_Store
|
||||
|
||||
/web_src/**/*.RData
|
||||
/web_src/**/*.pdf
|
||||
/web_src/**/*_files
|
||||
/web_src/**/*_cache
|
||||
/.luarc.json
|
||||
/sandbox
|
||||
*.log
|
||||
ncbitaxo_*
|
||||
Readme_files
|
||||
Readme.html
|
||||
tmp.*
|
||||
1
.vscode/ltex.hiddenFalsePositives.en-US.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
{"rule":"MORFOLOGIK_RULE_EN_US","sentence":"^\\QA password that secures access to the system\nA user number or UID (User IDentifier) that identifies the user on the machine\nA location on the hard disk to store the user's files, called Home or home\nA group of users, which allows working in groups on the machine (see later)\\E$"}
|
||||
709
Readme.html
Normal file
@@ -0,0 +1,709 @@
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head>
|
||||
|
||||
<meta charset="utf-8">
|
||||
<meta name="generator" content="quarto-1.8.26">
|
||||
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
|
||||
|
||||
|
||||
<title>readme</title>
|
||||
<style>
|
||||
code{white-space: pre-wrap;}
|
||||
span.smallcaps{font-variant: small-caps;}
|
||||
div.columns{display: flex; gap: min(4vw, 1.5em);}
|
||||
div.column{flex: auto; overflow-x: auto;}
|
||||
div.hanging-indent{margin-left: 1.5em; text-indent: -1.5em;}
|
||||
ul.task-list{list-style: none;}
|
||||
ul.task-list li input[type="checkbox"] {
|
||||
width: 0.8em;
|
||||
margin: 0 0.8em 0.2em -1em; /* quarto-specific, see https://github.com/quarto-dev/quarto-cli/issues/4556 */
|
||||
vertical-align: middle;
|
||||
}
|
||||
/* CSS for syntax highlighting */
|
||||
html { -webkit-text-size-adjust: 100%; }
|
||||
pre > code.sourceCode { white-space: pre; position: relative; }
|
||||
pre > code.sourceCode > span { display: inline-block; line-height: 1.25; }
|
||||
pre > code.sourceCode > span:empty { height: 1.2em; }
|
||||
.sourceCode { overflow: visible; }
|
||||
code.sourceCode > span { color: inherit; text-decoration: inherit; }
|
||||
div.sourceCode { margin: 1em 0; }
|
||||
pre.sourceCode { margin: 0; }
|
||||
@media screen {
|
||||
div.sourceCode { overflow: auto; }
|
||||
}
|
||||
@media print {
|
||||
pre > code.sourceCode { white-space: pre-wrap; }
|
||||
pre > code.sourceCode > span { text-indent: -5em; padding-left: 5em; }
|
||||
}
|
||||
pre.numberSource code
|
||||
{ counter-reset: source-line 0; }
|
||||
pre.numberSource code > span
|
||||
{ position: relative; left: -4em; counter-increment: source-line; }
|
||||
pre.numberSource code > span > a:first-child::before
|
||||
{ content: counter(source-line);
|
||||
position: relative; left: -1em; text-align: right; vertical-align: baseline;
|
||||
border: none; display: inline-block;
|
||||
-webkit-touch-callout: none; -webkit-user-select: none;
|
||||
-khtml-user-select: none; -moz-user-select: none;
|
||||
-ms-user-select: none; user-select: none;
|
||||
padding: 0 4px; width: 4em;
|
||||
}
|
||||
pre.numberSource { margin-left: 3em; padding-left: 4px; }
|
||||
div.sourceCode
|
||||
{ }
|
||||
@media screen {
|
||||
pre > code.sourceCode > span > a:first-child::before { text-decoration: underline; }
|
||||
}
|
||||
</style>
|
||||
|
||||
|
||||
<script src="Readme_files/libs/clipboard/clipboard.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/quarto.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/tabsets/tabsets.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/axe/axe-check.js" type="module"></script>
|
||||
<script src="Readme_files/libs/quarto-html/popper.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/tippy.umd.min.js"></script>
|
||||
<script src="Readme_files/libs/quarto-html/anchor.min.js"></script>
|
||||
<link href="Readme_files/libs/quarto-html/tippy.css" rel="stylesheet">
|
||||
<link href="Readme_files/libs/quarto-html/quarto-syntax-highlighting-587c61ba64f3a5504c4d52d930310e48.css" rel="stylesheet" id="quarto-text-highlighting-styles">
|
||||
<script src="Readme_files/libs/bootstrap/bootstrap.min.js"></script>
|
||||
<link href="Readme_files/libs/bootstrap/bootstrap-icons.css" rel="stylesheet">
|
||||
<link href="Readme_files/libs/bootstrap/bootstrap-d6a003b94517c951b2d65075d42fb01b.min.css" rel="stylesheet" append-hash="true" id="quarto-bootstrap" data-mode="light">
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
<body class="fullcontent quarto-light">
|
||||
|
||||
<div id="quarto-content" class="page-columns page-rows-contents page-layout-article">
|
||||
|
||||
<main class="content" id="quarto-document-content">
|
||||
|
||||
|
||||
|
||||
|
||||
<section id="obijupyterhub---the-dna-metabarcoding-learning-server" class="level1">
|
||||
<h1>OBIJupyterHub - the DNA Metabarcoding Learning Server</h1>
|
||||
<section id="intended-use" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="intended-use">Intended use</h2>
|
||||
<p>This project packages the MetabarcodingSchool training lab into one reproducible bundle. You get Python, R, and Bash kernels, a Quarto-built course website, and preconfigured admin/student accounts, so onboarding a class is a single command instead of a day of setup. Everything runs locally on a single machine, student work persists between sessions, and <code>./start-jupyterhub.sh</code> takes care of building images, rendering the site, preparing volumes, and bringing JupyterHub up at <code>http://localhost:8888</code>. Defaults (accounts, passwords, volumes) live in the repo so instructors can tweak them quickly.</p>
|
||||
</section>
|
||||
<section id="prerequisites-with-quick-checks" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="prerequisites-with-quick-checks">Prerequisites (with quick checks)</h2>
|
||||
<p>You need Docker, Docker Compose, Quarto, and Python 3 available on the machine that will host the lab.</p>
|
||||
<ul>
|
||||
<li>macOS: install <a href="https://orbstack.dev/">OrbStack</a> (recommended) or Docker Desktop; both ship Docker Engine and Compose.</li>
|
||||
<li>Linux: install Docker Engine and the Compose plugin from your distribution (e.g., <code>sudo apt install docker.io docker-compose-plugin</code>) or from Docker’s official packages.</li>
|
||||
<li>Windows: install Docker Desktop with the WSL2 backend enabled.</li>
|
||||
<li>Quarto CLI: get installers from <a href="https://quarto.org/docs/get-started/" class="uri">https://quarto.org/docs/get-started/</a>.</li>
|
||||
<li>Python 3: any recent version is fine (only the standard library is used).</li>
|
||||
</ul>
|
||||
<p>Verify from a terminal; if a command is missing, install it before moving on:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb1"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> <span class="at">--version</span></span>
|
||||
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> compose version <span class="co"># or: docker-compose --version</span></span>
|
||||
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true" tabindex="-1"></a><span class="ex">quarto</span> <span class="at">--version</span></span>
|
||||
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true" tabindex="-1"></a><span class="ex">python3</span> <span class="at">--version</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="how-the-startup-script-works" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="how-the-startup-script-works">How the startup script works</h2>
|
||||
<p><code>./start-jupyterhub.sh</code> is the single entry point. It builds the Docker images, renders the course website, prepares the volume folders, and starts the stack. Internally it:</p>
|
||||
<ul>
|
||||
<li>creates the <code>jupyterhub_volumes/</code> tree (caddy, course, shared, users, web…)</li>
|
||||
<li>builds <code>jupyterhub-student</code> and <code>jupyterhub-hub</code> images</li>
|
||||
<li>renders the Quarto site from <code>web_src/</code>, generates PDF galleries and <code>pages.json</code>, and copies everything into <code>jupyterhub_volumes/web/</code></li>
|
||||
<li>runs <code>docker-compose up -d --remove-orphans</code></li>
|
||||
</ul>
|
||||
<p>You can tailor what it does with a few flags:</p>
|
||||
<ul>
|
||||
<li><code>--no-build</code> (or <code>--offline</code>): skip Docker image builds and reuse existing images (useful when offline).</li>
|
||||
<li><code>--force-rebuild</code>: rebuild images without cache.</li>
|
||||
<li><code>--stop-server</code>: stop the stack and remove student containers, then exit.</li>
|
||||
<li><code>--update-lectures</code>: rebuild the course website only (no Docker stop/start).</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="installation-and-first-run" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="installation-and-first-run">Installation and first run</h2>
|
||||
<ol type="1">
|
||||
<li>Clone the project:</li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb2"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><a href="#cb2-1" aria-hidden="true" tabindex="-1"></a><span class="fu">git</span> clone https://forge.metabarcoding.org/MetabarcodingSchool/OBIJupyterHub.git</span>
|
||||
<span id="cb2-2"><a href="#cb2-2" aria-hidden="true" tabindex="-1"></a><span class="bu">cd</span> OBIJupyterHub</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<ol start="2" type="1">
|
||||
<li>(Optional) glance at the structure you’ll populate:</li>
|
||||
</ol>
|
||||
<pre><code>OBIJupyterHub
|
||||
├── start-jupyterhub.sh - single entry point (build + render + start)
|
||||
├── obijupyterhub - Docker images and stack definitions
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── Dockerfile
|
||||
│ ├── Dockerfile.hub
|
||||
│ └── jupyterhub_config.py
|
||||
├── jupyterhub_volumes - data persisted on the host
|
||||
│ ├── course - read-only for students (notebooks, data, bin, R packages)
|
||||
│ ├── shared - shared read/write space for everyone
|
||||
│ ├── users - per-user persistent data
|
||||
│ └── web - rendered course website
|
||||
└── web_src - Quarto sources for the course website</code></pre>
|
||||
<ol start="3" type="1">
|
||||
<li>Prepare course materials (optional before first run):</li>
|
||||
</ol>
|
||||
<ul>
|
||||
<li>Put notebooks, datasets, scripts, binaries, or PDFs for students under <code>jupyterhub_volumes/course/</code>. They will appear read-only at <code>/home/jovyan/work/course/</code>.</li>
|
||||
<li>For collaborative work, drop files in <code>jupyterhub_volumes/shared/</code> (read/write for all at <code>/home/jovyan/work/shared/</code>).</li>
|
||||
<li>Edit or add Quarto sources in <code>web_src/</code> to update the course website; the script will render them.</li>
|
||||
</ul>
|
||||
<ol start="4" type="1">
|
||||
<li>Start everything (build + render + launch):</li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb4"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true" tabindex="-1"></a><span class="ex">./start-jupyterhub.sh</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<ol start="5" type="1">
|
||||
<li><p>Access JupyterHub in a browser at <code>http://localhost:8888</code>.</p></li>
|
||||
<li><p>Stop the stack when you’re done (run from <code>obijupyterhub/</code>):</p></li>
|
||||
</ol>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb5"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true" tabindex="-1"></a><span class="ex">docker-compose</span> down</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<section id="operating-the-stack-one-command-a-few-options" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="operating-the-stack-one-command-a-few-options">Operating the stack (one command, a few options)</h3>
|
||||
<ul>
|
||||
<li>Start or rebuild: <code>./start-jupyterhub.sh</code> (rebuilds images, regenerates the website, starts the stack).</li>
|
||||
<li>Start without rebuilding images (offline): <code>./start-jupyterhub.sh --no-build</code></li>
|
||||
<li>Force rebuild without cache: <code>./start-jupyterhub.sh --force-rebuild</code></li>
|
||||
<li>Stop only: <code>./start-jupyterhub.sh --stop-server</code></li>
|
||||
<li>Rebuild website only (no Docker stop/start): <code>./start-jupyterhub.sh --update-lectures</code></li>
|
||||
<li>Access at <code>http://localhost:8888</code> (students: any username / password <code>metabar2025</code>; admin: <code>admin</code> / <code>admin2025</code>).</li>
|
||||
<li>Check logs from <code>obijupyterhub/</code> with <code>docker-compose logs -f jupyterhub</code>.</li>
|
||||
<li>Stop with <code>docker-compose down</code> (from <code>obijupyterhub/</code>). Rerun <code>./start-jupyterhub.sh</code> to start again or after config changes.</li>
|
||||
</ul>
|
||||
</section>
|
||||
</section>
|
||||
<section id="managing-shared-data" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="managing-shared-data">Managing shared data</h2>
|
||||
<p>Each student lands in <code>/home/jovyan/work/</code> with three key areas: their own files, a shared space, and a read-only course space. Everything under <code>work/</code> is persisted on the host in <code>jupyterhub_volumes</code>.</p>
|
||||
<pre><code>work/ # Personal workspace root (persistent)
|
||||
├── [student files] # Their own files and notebooks
|
||||
├── R_packages/ # Personal R packages (writable by student)
|
||||
├── shared/ # Shared workspace (read/write, shared with all)
|
||||
└── course/ # Course files (read-only, managed by admin)
|
||||
├── R_packages/ # Shared R packages (read-only, installed by prof)
|
||||
├── bin/ # Shared executables (in PATH)
|
||||
└── [course materials] # Your course files</code></pre>
|
||||
<p>R looks for packages in this order: personal <code>work/R_packages/</code>, then shared <code>work/course/R_packages/</code>, then system libraries. Because everything lives under <code>work/</code>, student files survive restarts.</p>
|
||||
<section id="user-accounts" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="user-accounts">User Accounts</h3>
|
||||
<p>Defaults are defined in <code>obijupyterhub/docker-compose.yml</code>: admin (<code>admin</code> / <code>admin2025</code>) with write access to <code>course/</code>, and students (any username, password <code>metabar2025</code>) with read-only access to <code>course/</code>. Adjust <code>JUPYTERHUB_ADMIN_PASSWORD</code> and <code>JUPYTERHUB_PASSWORD</code> there, then rerun <code>./start-jupyterhub.sh</code>.</p>
|
||||
</section>
|
||||
<section id="installing-r-packages-admin-only" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="installing-r-packages-admin-only">Installing R Packages (Admin Only)</h3>
|
||||
<p>From the host, install shared R packages into <code>course/R_packages/</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb7"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Install packages</span></span>
|
||||
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true" tabindex="-1"></a><span class="ex">tools/install_packages.sh</span> reshape2 plotly knitr</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Students can install their own packages into their personal <code>work/R_packages/</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb8"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true" tabindex="-1"></a><span class="co"># Install in personal library (each student has their own)</span></span>
|
||||
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true" tabindex="-1"></a><span class="fu">install.packages</span>(<span class="st">'mypackage'</span>) <span class="co"># Will install in work/R_packages/</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="using-r-packages-students" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="using-r-packages-students">Using R Packages (Students)</h3>
|
||||
<p>Students simply load packages normally:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb9"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(reshape2) <span class="co"># R checks: 1) work/R_packages/ 2) work/course/R_packages/ 3) system</span></span>
|
||||
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true" tabindex="-1"></a><span class="fu">library</span>(plotly)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>R automatically searches in this order:</p>
|
||||
<ol type="1">
|
||||
<li>Personal packages: <code>/home/jovyan/work/R_packages/</code> (R_LIBS_USER)</li>
|
||||
<li>Prof packages: <code>/home/jovyan/work/course/R_packages/</code> (R_LIBS_SITE)</li>
|
||||
<li>System packages</li>
|
||||
</ol>
|
||||
</section>
|
||||
<section id="list-available-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="list-available-packages">List Available Packages</h3>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb10"><pre class="sourceCode r code-with-copy"><code class="sourceCode r"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true" tabindex="-1"></a><span class="co"># List all available packages (personal + course + system)</span></span>
|
||||
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true" tabindex="-1"></a><span class="fu">installed.packages</span>()[,<span class="st">"Package"</span>]</span>
|
||||
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true" tabindex="-1"></a><span class="co"># Check personal packages</span></span>
|
||||
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true" tabindex="-1"></a><span class="fu">list.files</span>(<span class="st">"/home/jovyan/work/R_packages"</span>)</span>
|
||||
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true" tabindex="-1"></a><span class="co"># Check course packages (installed by prof)</span></span>
|
||||
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true" tabindex="-1"></a><span class="fu">list.files</span>(<span class="st">"/home/jovyan/work/course/R_packages"</span>)</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="deposit-or-retrieve-course-and-student-files" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="deposit-or-retrieve-course-and-student-files">Deposit or retrieve course and student files</h3>
|
||||
<p>On the host, place course files in <code>jupyterhub_volumes/course/</code> (they appear read-only to students), shared files in <code>jupyterhub_volumes/shared/</code>, and collect student work from <code>jupyterhub_volumes/users/</code>.</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="user-management" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="user-management">User Management</h2>
|
||||
<section id="option-1-predefined-user-list" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="option-1-predefined-user-list">Option 1: Predefined User List</h3>
|
||||
<p>In <code>jupyterhub_config.py</code>, uncomment and modify:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb11"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true" tabindex="-1"></a>c.Authenticator.allowed_users <span class="op">=</span> {<span class="st">'student1'</span>, <span class="st">'student2'</span>, <span class="st">'student3'</span>}</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
<section id="option-2-allow-everyone-for-testing" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="option-2-allow-everyone-for-testing">Option 2: Allow Everyone (for testing)</h3>
|
||||
<p>By default, the configuration allows any user:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb12"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true" tabindex="-1"></a>c.Authenticator.allow_all <span class="op">=</span> <span class="va">True</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>⚠️ <strong>Warning</strong>: DummyAuthenticator is ONLY for local testing!</p>
|
||||
</section>
|
||||
</section>
|
||||
<section id="kernel-verification" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="kernel-verification">Kernel Verification</h2>
|
||||
<p>Once logged in, create a new notebook and verify you have access to:</p>
|
||||
<ul>
|
||||
<li><strong>Python 3</strong> (default kernel)</li>
|
||||
<li><strong>R</strong> (R kernel)</li>
|
||||
<li><strong>Bash</strong> (bash kernel)</li>
|
||||
</ul>
|
||||
</section>
|
||||
<section id="customization-for-your-labs" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="customization-for-your-labs">Customization for Your Labs</h2>
|
||||
<section id="add-additional-r-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="add-additional-r-packages">Add Additional R Packages</h3>
|
||||
<p>Modify the <code>Dockerfile</code> (before <code>USER ${NB_UID}</code>):</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb13"><pre class="sourceCode dockerfile code-with-copy"><code class="sourceCode dockerfile"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true" tabindex="-1"></a><span class="kw">RUN</span> <span class="ex">R</span> <span class="at">-e</span> <span class="st">"install.packages(c('your_package'), repos='http://cran.rstudio.com/')"</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Then rerun <code>./start-jupyterhub.sh</code> to rebuild and restart.</p>
|
||||
</section>
|
||||
<section id="add-python-packages" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="add-python-packages">Add Python Packages</h3>
|
||||
<p>Add to the <code>Dockerfile</code> (before <code>USER ${NB_UID}</code>):</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb14"><pre class="sourceCode dockerfile code-with-copy"><code class="sourceCode dockerfile"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true" tabindex="-1"></a><span class="kw">RUN</span> <span class="ex">pip</span> install numpy pandas matplotlib seaborn</span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
<p>Then rerun <code>./start-jupyterhub.sh</code> to rebuild and restart.</p>
|
||||
</section>
|
||||
<section id="change-port-if-8000-is-occupied" class="level3">
|
||||
<h3 class="anchored" data-anchor-id="change-port-if-8000-is-occupied">Change Port (if 8000 is occupied)</h3>
|
||||
<p>Modify in <code>docker-compose.yml</code>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb15"><pre class="sourceCode yaml code-with-copy"><code class="sourceCode yaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true" tabindex="-1"></a><span class="fu">ports</span><span class="kw">:</span></span>
|
||||
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true" tabindex="-1"></a><span class="at"> </span><span class="kw">-</span><span class="at"> </span><span class="st">"8001:8000"</span><span class="co"> # Accessible on localhost:8001</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
</section>
|
||||
<section id="advantages-of-this-approach" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="advantages-of-this-approach">Advantages of This Approach</h2>
|
||||
<p>✅ <strong>Everything in Docker</strong>: No need to install Python/JupyterHub on your computer<br>
|
||||
✅ <strong>Portable</strong>: Easy to deploy on another server<br>
|
||||
✅ <strong>Isolated</strong>: No pollution of your system environment<br>
|
||||
✅ <strong>Easy to Clean</strong>: A simple <code>docker-compose down</code> is enough<br>
|
||||
✅ <strong>Reproducible</strong>: Students will have exactly the same environment</p>
|
||||
</section>
|
||||
<section id="troubleshooting" class="level2">
|
||||
<h2 class="anchored" data-anchor-id="troubleshooting">Troubleshooting</h2>
|
||||
<ul>
|
||||
<li>Docker daemon unavailable: make sure OrbStack/Docker Desktop/daemon is running; verify <code>/var/run/docker.sock</code> exists.</li>
|
||||
<li>Student containers do not start: check <code>docker-compose logs jupyterhub</code> and confirm the images exist with <code>docker images | grep jupyterhub-student</code>.</li>
|
||||
<li>Port conflict: change the published port in <code>docker-compose.yml</code>.</li>
|
||||
</ul>
|
||||
<p><strong>I want to start from scratch</strong>:</p>
|
||||
<div class="code-copy-outer-scaffold"><div class="sourceCode" id="cb16"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true" tabindex="-1"></a><span class="bu">pushd</span> obijupyterhub</span>
|
||||
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true" tabindex="-1"></a><span class="ex">docker-compose</span> down <span class="at">-v</span></span>
|
||||
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true" tabindex="-1"></a><span class="ex">docker</span> rmi jupyterhub-hub jupyterhub-student</span>
|
||||
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true" tabindex="-1"></a><span class="bu">popd</span></span>
|
||||
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true" tabindex="-1"></a></span>
|
||||
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true" tabindex="-1"></a><span class="co"># Then rebuild everything</span></span>
|
||||
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true" tabindex="-1"></a><span class="ex">./start-jupyterhub.sh</span></span></code></pre></div><button title="Copy to Clipboard" class="code-copy-button"><i class="bi"></i></button></div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
</main>
|
||||
<!-- /main column -->
|
||||
<script id="quarto-html-after-body" type="application/javascript">
|
||||
window.document.addEventListener("DOMContentLoaded", function (event) {
|
||||
const icon = "";
|
||||
const anchorJS = new window.AnchorJS();
|
||||
anchorJS.options = {
|
||||
placement: 'right',
|
||||
icon: icon
|
||||
};
|
||||
anchorJS.add('.anchored');
|
||||
const isCodeAnnotation = (el) => {
|
||||
for (const clz of el.classList) {
|
||||
if (clz.startsWith('code-annotation-')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
const onCopySuccess = function(e) {
|
||||
// button target
|
||||
const button = e.trigger;
|
||||
// don't keep focus
|
||||
button.blur();
|
||||
// flash "checked"
|
||||
button.classList.add('code-copy-button-checked');
|
||||
var currentTitle = button.getAttribute("title");
|
||||
button.setAttribute("title", "Copied!");
|
||||
let tooltip;
|
||||
if (window.bootstrap) {
|
||||
button.setAttribute("data-bs-toggle", "tooltip");
|
||||
button.setAttribute("data-bs-placement", "left");
|
||||
button.setAttribute("data-bs-title", "Copied!");
|
||||
tooltip = new bootstrap.Tooltip(button,
|
||||
{ trigger: "manual",
|
||||
customClass: "code-copy-button-tooltip",
|
||||
offset: [0, -8]});
|
||||
tooltip.show();
|
||||
}
|
||||
setTimeout(function() {
|
||||
if (tooltip) {
|
||||
tooltip.hide();
|
||||
button.removeAttribute("data-bs-title");
|
||||
button.removeAttribute("data-bs-toggle");
|
||||
button.removeAttribute("data-bs-placement");
|
||||
}
|
||||
button.setAttribute("title", currentTitle);
|
||||
button.classList.remove('code-copy-button-checked');
|
||||
}, 1000);
|
||||
// clear code selection
|
||||
e.clearSelection();
|
||||
}
|
||||
const getTextToCopy = function(trigger) {
|
||||
const outerScaffold = trigger.parentElement.cloneNode(true);
|
||||
const codeEl = outerScaffold.querySelector('code');
|
||||
for (const childEl of codeEl.children) {
|
||||
if (isCodeAnnotation(childEl)) {
|
||||
childEl.remove();
|
||||
}
|
||||
}
|
||||
return codeEl.innerText;
|
||||
}
|
||||
const clipboard = new window.ClipboardJS('.code-copy-button:not([data-in-quarto-modal])', {
|
||||
text: getTextToCopy
|
||||
});
|
||||
clipboard.on('success', onCopySuccess);
|
||||
if (window.document.getElementById('quarto-embedded-source-code-modal')) {
|
||||
const clipboardModal = new window.ClipboardJS('.code-copy-button[data-in-quarto-modal]', {
|
||||
text: getTextToCopy,
|
||||
container: window.document.getElementById('quarto-embedded-source-code-modal')
|
||||
});
|
||||
clipboardModal.on('success', onCopySuccess);
|
||||
}
|
||||
var localhostRegex = new RegExp(/^(?:http|https):\/\/localhost\:?[0-9]*\//);
|
||||
var mailtoRegex = new RegExp(/^mailto:/);
|
||||
var filterRegex = new RegExp('/' + window.location.host + '/');
|
||||
var isInternal = (href) => {
|
||||
return filterRegex.test(href) || localhostRegex.test(href) || mailtoRegex.test(href);
|
||||
}
|
||||
// Inspect non-navigation links and adorn them if external
|
||||
var links = window.document.querySelectorAll('a[href]:not(.nav-link):not(.navbar-brand):not(.toc-action):not(.sidebar-link):not(.sidebar-item-toggle):not(.pagination-link):not(.no-external):not([aria-hidden]):not(.dropdown-item):not(.quarto-navigation-tool):not(.about-link)');
|
||||
for (var i=0; i<links.length; i++) {
|
||||
const link = links[i];
|
||||
if (!isInternal(link.href)) {
|
||||
// undo the damage that might have been done by quarto-nav.js in the case of
|
||||
// links that we want to consider external
|
||||
if (link.dataset.originalHref !== undefined) {
|
||||
link.href = link.dataset.originalHref;
|
||||
}
|
||||
}
|
||||
}
|
||||
function tippyHover(el, contentFn, onTriggerFn, onUntriggerFn) {
|
||||
const config = {
|
||||
allowHTML: true,
|
||||
maxWidth: 500,
|
||||
delay: 100,
|
||||
arrow: false,
|
||||
appendTo: function(el) {
|
||||
return el.parentElement;
|
||||
},
|
||||
interactive: true,
|
||||
interactiveBorder: 10,
|
||||
theme: 'quarto',
|
||||
placement: 'bottom-start',
|
||||
};
|
||||
if (contentFn) {
|
||||
config.content = contentFn;
|
||||
}
|
||||
if (onTriggerFn) {
|
||||
config.onTrigger = onTriggerFn;
|
||||
}
|
||||
if (onUntriggerFn) {
|
||||
config.onUntrigger = onUntriggerFn;
|
||||
}
|
||||
window.tippy(el, config);
|
||||
}
|
||||
const noterefs = window.document.querySelectorAll('a[role="doc-noteref"]');
|
||||
for (var i=0; i<noterefs.length; i++) {
|
||||
const ref = noterefs[i];
|
||||
tippyHover(ref, function() {
|
||||
// use id or data attribute instead here
|
||||
let href = ref.getAttribute('data-footnote-href') || ref.getAttribute('href');
|
||||
try { href = new URL(href).hash; } catch {}
|
||||
const id = href.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
if (note) {
|
||||
return note.innerHTML;
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
});
|
||||
}
|
||||
const xrefs = window.document.querySelectorAll('a.quarto-xref');
|
||||
const processXRef = (id, note) => {
|
||||
// Strip column container classes
|
||||
const stripColumnClz = (el) => {
|
||||
el.classList.remove("page-full", "page-columns");
|
||||
if (el.children) {
|
||||
for (const child of el.children) {
|
||||
stripColumnClz(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
stripColumnClz(note)
|
||||
if (id === null || id.startsWith('sec-')) {
|
||||
// Special case sections, only their first couple elements
|
||||
const container = document.createElement("div");
|
||||
if (note.children && note.children.length > 2) {
|
||||
container.appendChild(note.children[0].cloneNode(true));
|
||||
for (let i = 1; i < note.children.length; i++) {
|
||||
const child = note.children[i];
|
||||
if (child.tagName === "P" && child.innerText === "") {
|
||||
continue;
|
||||
} else {
|
||||
container.appendChild(child.cloneNode(true));
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(container);
|
||||
}
|
||||
return container.innerHTML
|
||||
} else {
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(note);
|
||||
}
|
||||
return note.innerHTML;
|
||||
}
|
||||
} else {
|
||||
// Remove any anchor links if they are present
|
||||
const anchorLink = note.querySelector('a.anchorjs-link');
|
||||
if (anchorLink) {
|
||||
anchorLink.remove();
|
||||
}
|
||||
if (window.Quarto?.typesetMath) {
|
||||
window.Quarto.typesetMath(note);
|
||||
}
|
||||
if (note.classList.contains("callout")) {
|
||||
return note.outerHTML;
|
||||
} else {
|
||||
return note.innerHTML;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (var i=0; i<xrefs.length; i++) {
|
||||
const xref = xrefs[i];
|
||||
tippyHover(xref, undefined, function(instance) {
|
||||
instance.disable();
|
||||
let url = xref.getAttribute('href');
|
||||
let hash = undefined;
|
||||
if (url.startsWith('#')) {
|
||||
hash = url;
|
||||
} else {
|
||||
try { hash = new URL(url).hash; } catch {}
|
||||
}
|
||||
if (hash) {
|
||||
const id = hash.replace(/^#\/?/, "");
|
||||
const note = window.document.getElementById(id);
|
||||
if (note !== null) {
|
||||
try {
|
||||
const html = processXRef(id, note.cloneNode(true));
|
||||
instance.setContent(html);
|
||||
} finally {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
}
|
||||
} else {
|
||||
// See if we can fetch this
|
||||
fetch(url.split('#')[0])
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(html, "text/html");
|
||||
const note = htmlDoc.getElementById(id);
|
||||
if (note !== null) {
|
||||
const html = processXRef(id, note);
|
||||
instance.setContent(html);
|
||||
}
|
||||
}).finally(() => {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
});
|
||||
}
|
||||
} else {
|
||||
// See if we can fetch a full url (with no hash to target)
|
||||
// This is a special case and we should probably do some content thinning / targeting
|
||||
fetch(url)
|
||||
.then(res => res.text())
|
||||
.then(html => {
|
||||
const parser = new DOMParser();
|
||||
const htmlDoc = parser.parseFromString(html, "text/html");
|
||||
const note = htmlDoc.querySelector('main.content');
|
||||
if (note !== null) {
|
||||
// This should only happen for chapter cross references
|
||||
// (since there is no id in the URL)
|
||||
// remove the first header
|
||||
if (note.children.length > 0 && note.children[0].tagName === "HEADER") {
|
||||
note.children[0].remove();
|
||||
}
|
||||
const html = processXRef(null, note);
|
||||
instance.setContent(html);
|
||||
}
|
||||
}).finally(() => {
|
||||
instance.enable();
|
||||
instance.show();
|
||||
});
|
||||
}
|
||||
}, function(instance) {
|
||||
});
|
||||
}
|
||||
let selectedAnnoteEl;
|
||||
const selectorForAnnotation = ( cell, annotation) => {
|
||||
let cellAttr = 'data-code-cell="' + cell + '"';
|
||||
let lineAttr = 'data-code-annotation="' + annotation + '"';
|
||||
const selector = 'span[' + cellAttr + '][' + lineAttr + ']';
|
||||
return selector;
|
||||
}
|
||||
const selectCodeLines = (annoteEl) => {
|
||||
const doc = window.document;
|
||||
const targetCell = annoteEl.getAttribute("data-target-cell");
|
||||
const targetAnnotation = annoteEl.getAttribute("data-target-annotation");
|
||||
const annoteSpan = window.document.querySelector(selectorForAnnotation(targetCell, targetAnnotation));
|
||||
const lines = annoteSpan.getAttribute("data-code-lines").split(",");
|
||||
const lineIds = lines.map((line) => {
|
||||
return targetCell + "-" + line;
|
||||
})
|
||||
let top = null;
|
||||
let height = null;
|
||||
let parent = null;
|
||||
if (lineIds.length > 0) {
|
||||
//compute the position of the single el (top and bottom and make a div)
|
||||
const el = window.document.getElementById(lineIds[0]);
|
||||
top = el.offsetTop;
|
||||
height = el.offsetHeight;
|
||||
parent = el.parentElement.parentElement;
|
||||
if (lineIds.length > 1) {
|
||||
const lastEl = window.document.getElementById(lineIds[lineIds.length - 1]);
|
||||
const bottom = lastEl.offsetTop + lastEl.offsetHeight;
|
||||
height = bottom - top;
|
||||
}
|
||||
if (top !== null && height !== null && parent !== null) {
|
||||
// cook up a div (if necessary) and position it
|
||||
let div = window.document.getElementById("code-annotation-line-highlight");
|
||||
if (div === null) {
|
||||
div = window.document.createElement("div");
|
||||
div.setAttribute("id", "code-annotation-line-highlight");
|
||||
div.style.position = 'absolute';
|
||||
parent.appendChild(div);
|
||||
}
|
||||
div.style.top = top - 2 + "px";
|
||||
div.style.height = height + 4 + "px";
|
||||
div.style.left = 0;
|
||||
let gutterDiv = window.document.getElementById("code-annotation-line-highlight-gutter");
|
||||
if (gutterDiv === null) {
|
||||
gutterDiv = window.document.createElement("div");
|
||||
gutterDiv.setAttribute("id", "code-annotation-line-highlight-gutter");
|
||||
gutterDiv.style.position = 'absolute';
|
||||
const codeCell = window.document.getElementById(targetCell);
|
||||
const gutter = codeCell.querySelector('.code-annotation-gutter');
|
||||
gutter.appendChild(gutterDiv);
|
||||
}
|
||||
gutterDiv.style.top = top - 2 + "px";
|
||||
gutterDiv.style.height = height + 4 + "px";
|
||||
}
|
||||
selectedAnnoteEl = annoteEl;
|
||||
}
|
||||
};
|
||||
const unselectCodeLines = () => {
|
||||
const elementsIds = ["code-annotation-line-highlight", "code-annotation-line-highlight-gutter"];
|
||||
elementsIds.forEach((elId) => {
|
||||
const div = window.document.getElementById(elId);
|
||||
if (div) {
|
||||
div.remove();
|
||||
}
|
||||
});
|
||||
selectedAnnoteEl = undefined;
|
||||
};
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
elRect = undefined;
|
||||
if (selectedAnnoteEl) {
|
||||
selectCodeLines(selectedAnnoteEl);
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
function throttle(fn, ms) {
|
||||
let throttle = false;
|
||||
let timer;
|
||||
return (...args) => {
|
||||
if(!throttle) { // first call gets through
|
||||
fn.apply(this, args);
|
||||
throttle = true;
|
||||
} else { // all the others get throttled
|
||||
if(timer) clearTimeout(timer); // cancel #2
|
||||
timer = setTimeout(() => {
|
||||
fn.apply(this, args);
|
||||
timer = throttle = false;
|
||||
}, ms);
|
||||
}
|
||||
};
|
||||
}
|
||||
// Attach click handler to the DT
|
||||
const annoteDls = window.document.querySelectorAll('dt[data-target-cell]');
|
||||
for (const annoteDlNode of annoteDls) {
|
||||
annoteDlNode.addEventListener('click', (event) => {
|
||||
const clickedEl = event.target;
|
||||
if (clickedEl !== selectedAnnoteEl) {
|
||||
unselectCodeLines();
|
||||
const activeEl = window.document.querySelector('dt[data-target-cell].code-annotation-active');
|
||||
if (activeEl) {
|
||||
activeEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
selectCodeLines(clickedEl);
|
||||
clickedEl.classList.add('code-annotation-active');
|
||||
} else {
|
||||
// Unselect the line
|
||||
unselectCodeLines();
|
||||
clickedEl.classList.remove('code-annotation-active');
|
||||
}
|
||||
});
|
||||
}
|
||||
const findCites = (el) => {
|
||||
const parentEl = el.parentElement;
|
||||
if (parentEl) {
|
||||
const cites = parentEl.dataset.cites;
|
||||
if (cites) {
|
||||
return {
|
||||
el,
|
||||
cites: cites.split(' ')
|
||||
};
|
||||
} else {
|
||||
return findCites(el.parentElement)
|
||||
}
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
};
|
||||
var bibliorefs = window.document.querySelectorAll('a[role="doc-biblioref"]');
|
||||
for (var i=0; i<bibliorefs.length; i++) {
|
||||
const ref = bibliorefs[i];
|
||||
const citeInfo = findCites(ref);
|
||||
if (citeInfo) {
|
||||
tippyHover(citeInfo.el, function() {
|
||||
var popup = window.document.createElement('div');
|
||||
citeInfo.cites.forEach(function(cite) {
|
||||
var citeDiv = window.document.createElement('div');
|
||||
citeDiv.classList.add('hanging-indent');
|
||||
citeDiv.classList.add('csl-entry');
|
||||
var biblioDiv = window.document.getElementById('ref-' + cite);
|
||||
if (biblioDiv) {
|
||||
citeDiv.innerHTML = biblioDiv.innerHTML;
|
||||
}
|
||||
popup.appendChild(citeDiv);
|
||||
});
|
||||
return popup.innerHTML;
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div> <!-- /content -->
|
||||
|
||||
|
||||
|
||||
|
||||
</body></html>
|
||||
283
Readme.md
@@ -1,146 +1,106 @@
|
||||
# JupyterHub Configuration with OrbStack on Mac (all in Docker)
|
||||
# OBIJupyterHub - the DNA Metabarcoding Learning Server
|
||||
|
||||
## Prerequisites
|
||||
## Intended use
|
||||
|
||||
You must have docker running on your computer
|
||||
This project packages the MetabarcodingSchool training lab into one reproducible bundle. You get Python, R, and Bash kernels, a Quarto-built course website, and preconfigured admin/student accounts, so onboarding a class is a single command instead of a day of setup. Everything runs locally on a single machine, student work persists between sessions, and `./start-jupyterhub.sh` takes care of building images, rendering the site, preparing volumes, and bringing JupyterHub up at `http://localhost:8888`. Defaults (accounts, passwords, volumes) live in the repo so instructors can tweak them quickly.
|
||||
|
||||
- On MacOS, [OrbStack](https://orbstack.dev/ "A Docker implementation optimised for MacOS") is recommanded
|
||||
## Prerequisites (with quick checks)
|
||||
|
||||
## Installation Steps
|
||||
You need Docker, Docker Compose, Quarto, and Python 3 available on the machine that will host the lab.
|
||||
|
||||
### 1. Create Directory Structure
|
||||
- macOS: install [OrbStack](https://orbstack.dev/) (recommended) or Docker Desktop; both ship Docker Engine and Compose.
|
||||
- Linux: install Docker Engine and the Compose plugin from your distribution (e.g., `sudo apt install docker.io docker-compose-plugin`) or from Docker’s official packages.
|
||||
- Windows: install Docker Desktop with the WSL2 backend enabled.
|
||||
- Quarto CLI: get installers from <https://quarto.org/docs/get-started/>.
|
||||
- Python 3: any recent version is fine (only the standard library is used).
|
||||
|
||||
Verify from a terminal; if a command is missing, install it before moving on:
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
docker compose version # or: docker-compose --version
|
||||
quarto --version
|
||||
python3 --version
|
||||
```
|
||||
|
||||
## How the startup script works
|
||||
|
||||
`./start-jupyterhub.sh` is the single entry point. It builds the Docker images, renders the course website, prepares the volume folders, and starts the stack. Internally it:
|
||||
|
||||
- creates the `jupyterhub_volumes/` tree (caddy, course, shared, users, web…)
|
||||
- builds `jupyterhub-student` and `jupyterhub-hub` images
|
||||
- renders the Quarto site from `web_src/`, generates PDF galleries and `pages.json`, and copies everything into `jupyterhub_volumes/web/`
|
||||
- runs `docker-compose up -d --remove-orphans`
|
||||
|
||||
You can tailor what it does with a few flags:
|
||||
|
||||
- `--no-build` (or `--offline`): skip Docker image builds and reuse existing images (useful when offline).
|
||||
- `--force-rebuild`: rebuild images without cache.
|
||||
- `--stop-server`: stop the stack and remove student containers, then exit.
|
||||
- `--update-lectures`: rebuild the course website only (no Docker stop/start).
|
||||
- `--build-obidoc`: force rebuilding the obidoc documentation (auto-built if empty; skipped in offline mode).
|
||||
|
||||
## Installation and first run
|
||||
|
||||
1) Clone the project:
|
||||
|
||||
```bash
|
||||
git clone https://forge.metabarcoding.org/MetabarcodingSchool/OBIJupyterHub.git
|
||||
```
|
||||
|
||||
Enter into the `OBIJupyterHub` directory
|
||||
|
||||
```bash
|
||||
cd OBIJupyterHub
|
||||
```
|
||||
|
||||
#### File Structure
|
||||
|
||||
Your `OBIJupyterHub` directory should contain:
|
||||
2) (Optional) glance at the structure you’ll populate:
|
||||
|
||||
```
|
||||
OBIJupyterHub
|
||||
├── start-jupyterhub.sh - The script used to setup and start the server
|
||||
├── obijupyterhub - The files describing the docker images and the stack
|
||||
│ ├── Caddyfile
|
||||
├── start-jupyterhub.sh - single entry point (build + render + start)
|
||||
├── obijupyterhub - Docker images and stack definitions
|
||||
│ ├── docker-compose.yml
|
||||
│ ├── Dockerfile
|
||||
│ ├── Dockerfile.hub
|
||||
│ ├── jupyterhub_config.py
|
||||
│ ├── sftpgo_config.json
|
||||
│ └── start-notebook.sh
|
||||
├── jupyterhub_volumes - The directory containing the docker volumes
|
||||
│ ├── caddy
|
||||
│ ├── course - Read only volume mounted on every student container
|
||||
│ │ ├── bin
|
||||
│ │ └── R_packages
|
||||
│ ├── jupyterhub
|
||||
│ ├── shared - Read write volume shared in every student container
|
||||
│ ├── users
|
||||
│ └── web
|
||||
│ ├── img
|
||||
│ │ └── welcome_metabar.webp
|
||||
│ ├── index.html
|
||||
│ └── pages
|
||||
├── Readme.md - This documentation
|
||||
├── tools
|
||||
│ ├── generate_pages_json.py
|
||||
│ └── install_packages.sh
|
||||
└─── web_src - The quarto document sources used to build the web site
|
||||
├── _output
|
||||
├── _quarto.yml
|
||||
├── 00_home.qmd
|
||||
├── lectures
|
||||
│ └── computers
|
||||
│ └── regex
|
||||
│ ├── lecture_regex.qmd
|
||||
│ ├── slides_regex.qmd
|
||||
│ └── slides.css
|
||||
└── scripts
|
||||
└── copy-to-web.sh
|
||||
│ └── jupyterhub_config.py
|
||||
├── jupyterhub_volumes - data persisted on the host
|
||||
│ ├── course - read-only for students (notebooks, data, bin, R packages)
|
||||
│ ├── shared - shared read/write space for everyone
|
||||
│ ├── users - per-user persistent data
|
||||
│ └── web - rendered course website
|
||||
└── web_src - Quarto sources for the course website
|
||||
```
|
||||
|
||||
### 2. Start JupyterHub
|
||||
3) Prepare course materials (optional before first run):
|
||||
- Put notebooks, datasets, scripts, binaries, or PDFs for students under `jupyterhub_volumes/course/`. They will appear read-only at `/home/jovyan/work/course/`.
|
||||
- For collaborative work, drop files in `jupyterhub_volumes/shared/` (read/write for all at `/home/jovyan/work/shared/`).
|
||||
- Edit or add Quarto sources in `web_src/` to update the course website; the script will render them.
|
||||
|
||||
From the terminal, in the `OBIJupyterHub` directory, run the following command:
|
||||
4) Start everything (build + render + launch):
|
||||
|
||||
``` bash
|
||||
```bash
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
|
||||
### 3. Access JupyterHub
|
||||
5) Access JupyterHub in a browser at `http://localhost:8888`.
|
||||
|
||||
Open your browser and go to: **http://localhost:8888**
|
||||
6) Stop the stack when you’re done (run from `obijupyterhub/`):
|
||||
|
||||
You can log in as a student with any username and password: `metabar2025`
|
||||
|
||||
## Useful Commands
|
||||
|
||||
### View JupyterHub logs
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
docker-compose logs -f jupyterhub
|
||||
```
|
||||
|
||||
### View all containers (hub + students)
|
||||
|
||||
``` bash
|
||||
docker ps | grep jupyterhub
|
||||
```
|
||||
|
||||
### Stop JupyterHub
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
```bash
|
||||
docker-compose down
|
||||
```
|
||||
|
||||
### Restart JupyterHub (after config modification)
|
||||
### Operating the stack (one command, a few options)
|
||||
|
||||
``` bash
|
||||
cd obijupyterhub
|
||||
docker-compose restart jupyterhub
|
||||
```
|
||||
- Start or rebuild: `./start-jupyterhub.sh` (rebuilds images, regenerates the website, starts the stack).
|
||||
- Start without rebuilding images (offline): `./start-jupyterhub.sh --no-build`
|
||||
- Force rebuild without cache: `./start-jupyterhub.sh --force-rebuild`
|
||||
- Stop only: `./start-jupyterhub.sh --stop-server`
|
||||
- Rebuild website only (no Docker stop/start): `./start-jupyterhub.sh --update-lectures`
|
||||
- Rebuild obidoc docs: `./start-jupyterhub.sh --build-obidoc` (also builds automatically if `jupyterhub_volumes/web/obidoc` is empty; skipped in offline mode)
|
||||
- Access at `http://localhost:8888` (students: any username / password `metabar2025`; admin: `admin` / `admin2025`).
|
||||
- Check logs from `obijupyterhub/` with `docker-compose logs -f jupyterhub`.
|
||||
- Stop with `docker-compose down` (from `obijupyterhub/`). Rerun `./start-jupyterhub.sh` to start again or after config changes.
|
||||
|
||||
### View logs for a specific student
|
||||
## Managing shared data
|
||||
|
||||
``` bash
|
||||
docker logs jupyter-<username>
|
||||
```
|
||||
|
||||
Replace `<username>` by the actual username of the student.
|
||||
|
||||
### Clean up after lab
|
||||
|
||||
``` bash
|
||||
# Stop and remove all containers
|
||||
cd obijupyterhub
|
||||
docker-compose down
|
||||
|
||||
# Remove student containers
|
||||
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f
|
||||
|
||||
# Remove volumes (WARNING: deletes student data)
|
||||
docker volume ls | grep jupyterhub-user | awk '{print $2}' | xargs docker volume rm
|
||||
|
||||
# Clean everything (containers + volumes + network)
|
||||
docker-compose down -v
|
||||
docker ps -a | grep jupyter- | awk '{print $1}' | xargs docker rm -f
|
||||
docker volume prune -f
|
||||
```
|
||||
|
||||
## Managing Shared Data
|
||||
|
||||
### Directory Structure for Each Student
|
||||
|
||||
Each student will see this directory structure in their JupyterLab (everything under `work/` is persistent):
|
||||
Each student lands in `/home/jovyan/work/` with three key areas: their own files, a shared space, and a read-only course space. Everything under `work/` is persisted on the host in `jupyterhub_volumes`.
|
||||
|
||||
```
|
||||
work/ # Personal workspace root (persistent)
|
||||
@@ -153,42 +113,22 @@ work/ # Personal workspace root (persistent)
|
||||
└── [course materials] # Your course files
|
||||
```
|
||||
|
||||
**R Package Priority:**
|
||||
|
||||
1. R checks `work/R_packages/` first (personal, writable)
|
||||
1. Then `work/course/R_packages/` (shared, read-only, installed by prof)
|
||||
1. Then system libraries
|
||||
|
||||
**Important:** Everything is under `work/`, so all student files are automatically saved in their persistent volume.
|
||||
R looks for packages in this order: personal `work/R_packages/`, then shared `work/course/R_packages/`, then system libraries. Because everything lives under `work/`, student files survive restarts.
|
||||
|
||||
### User Accounts
|
||||
|
||||
**Admin Account:**
|
||||
|
||||
- Username: `admin`
|
||||
- Password: `admin2025` (change in docker-compose.yml: `JUPYTERHUB_ADMIN_PASSWORD`)
|
||||
- Can write to `course/` directory
|
||||
|
||||
**Student Accounts:**
|
||||
|
||||
- Username: any name
|
||||
- Password: `metabar2025` (change in docker-compose.yml: `JUPYTERHUB_PASSWORD`)
|
||||
- Read-only access to `course/` directory
|
||||
Defaults are defined in `obijupyterhub/docker-compose.yml`: admin (`admin` / `admin2025`) with write access to `course/`, and students (any username, password `metabar2025`) with read-only access to `course/`. Adjust `JUPYTERHUB_ADMIN_PASSWORD` and `JUPYTERHUB_PASSWORD` there, then rerun `./start-jupyterhub.sh`.
|
||||
|
||||
### Installing R Packages (Admin Only)
|
||||
|
||||
**From your Mac (recommended):**
|
||||
From the host, install shared R packages into `course/R_packages/`:
|
||||
|
||||
``` bash
|
||||
# Install packages
|
||||
tools/install_packages.sh reshape2 plotly knitr
|
||||
```
|
||||
|
||||
This script: - Installs packages in the `course/R_packages/` directory - All students can use them (read-only) - No need to rebuild the image
|
||||
|
||||
**Students can also install their own packages:**
|
||||
|
||||
Students can install packages in their personal `work/R_packages/`:
|
||||
Students can install their own packages into their personal `work/R_packages/`:
|
||||
|
||||
```r
|
||||
# Install in personal library (each student has their own)
|
||||
@@ -223,43 +163,9 @@ list.files("/home/jovyan/work/R_packages")
|
||||
list.files("/home/jovyan/work/course/R_packages")
|
||||
```
|
||||
|
||||
### Deposit Files for Course
|
||||
### Deposit or retrieve course and student files
|
||||
|
||||
To put files in the `course/` directory (accessible read-only):
|
||||
|
||||
``` bash
|
||||
# Create a temporary directory
|
||||
mkdir -p ~/jupyterhub-tp/course-files
|
||||
|
||||
# Copy your files into it
|
||||
cp my_notebooks.ipynb ~/jupyterhub-tp/course-files/
|
||||
cp my_data.csv ~/jupyterhub-tp/course-files/
|
||||
|
||||
# Copy into Docker volume
|
||||
docker run --rm \
|
||||
-v jupyterhub-course:/target \
|
||||
-v ~/jupyterhub-tp/course-files:/source \
|
||||
alpine sh -c "cp -r /source/* /target/"
|
||||
```
|
||||
|
||||
### Retrieve Student Work
|
||||
|
||||
``` bash
|
||||
# List user volumes
|
||||
docker volume ls | grep 'obijupyterhub_user-'
|
||||
|
||||
# Copy files from a specific student
|
||||
docker run --rm \
|
||||
-v obijupyterhub_user-alice:/source \
|
||||
-v ~/submissions:/target \
|
||||
alpine sh -c "cp -r /source/* /target/alice/"
|
||||
|
||||
# Copy all shared work
|
||||
docker run --rm \
|
||||
-v obijupyterhub_shared:/source \
|
||||
-v ~/submissions/shared:/target \
|
||||
alpine sh -c "cp -r /source/* /target/"
|
||||
```
|
||||
On the host, place course files in `jupyterhub_volumes/course/` (they appear read-only to students), shared files in `jupyterhub_volumes/shared/`, and collect student work from `jupyterhub_volumes/users/`.
|
||||
|
||||
## User Management
|
||||
|
||||
@@ -299,11 +205,7 @@ Modify the `Dockerfile` (before `USER ${NB_UID}`):
|
||||
RUN R -e "install.packages(c('your_package'), repos='http://cran.rstudio.com/')"
|
||||
```
|
||||
|
||||
Then restart the server (it rebuilds the images if needed):
|
||||
|
||||
```bash
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
Then rerun `./start-jupyterhub.sh` to rebuild and restart.
|
||||
|
||||
### Add Python Packages
|
||||
|
||||
@@ -313,14 +215,7 @@ Add to the `Dockerfile` (before `USER ${NB_UID}`):
|
||||
RUN pip install numpy pandas matplotlib seaborn
|
||||
```
|
||||
|
||||
### Distribute Files to Students
|
||||
|
||||
Create a `files_lab/` directory and add to the `Dockerfile`:
|
||||
|
||||
``` dockerfile
|
||||
COPY files_lab/ /home/${NB_USER}/lab/
|
||||
RUN chown -R ${NB_UID}:${NB_GID} /home/${NB_USER}/lab
|
||||
```
|
||||
Then rerun `./start-jupyterhub.sh` to rebuild and restart.
|
||||
|
||||
### Change Port (if 8000 is occupied)
|
||||
|
||||
@@ -341,29 +236,19 @@ ports:
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
**Error "Cannot connect to Docker daemon"**:
|
||||
|
||||
- Check that OrbStack is running
|
||||
- Verify the socket exists: `ls -la /var/run/docker.sock`
|
||||
|
||||
**Student containers don't start**:
|
||||
|
||||
- Check logs: `docker-compose logs jupyterhub`
|
||||
- Verify student image exists: `docker images | grep jupyterhub-student`
|
||||
|
||||
**Port 8000 already in use**:
|
||||
|
||||
- Change port in `docker-compose.yml`
|
||||
- Docker daemon unavailable: make sure OrbStack/Docker Desktop/daemon is running; verify `/var/run/docker.sock` exists.
|
||||
- Student containers do not start: check `docker-compose logs jupyterhub` and confirm the images exist with `docker images | grep jupyterhub-student`.
|
||||
- Port conflict: change the published port in `docker-compose.yml`.
|
||||
|
||||
|
||||
**I want to start from scratch**:
|
||||
|
||||
``` bash
|
||||
push obijupyterhub
|
||||
pushd obijupyterhub
|
||||
docker-compose down -v
|
||||
docker rmi jupyterhub-hub jupyterhub-student
|
||||
popd
|
||||
|
||||
# Then rebuild everything
|
||||
./start-jupyterhub.sh
|
||||
```
|
||||
```
|
||||
|
||||
12
Readme_files/libs/bootstrap/bootstrap-d6a003b94517c951b2d65075d42fb01b.min.css
vendored
Normal file
2106
Readme_files/libs/bootstrap/bootstrap-icons.css
vendored
Normal file
BIN
Readme_files/libs/bootstrap/bootstrap-icons.woff
Normal file
7
Readme_files/libs/bootstrap/bootstrap.min.js
vendored
Normal file
7
Readme_files/libs/clipboard/clipboard.min.js
vendored
Normal file
9
Readme_files/libs/quarto-html/anchor.min.js
vendored
Normal file
145
Readme_files/libs/quarto-html/axe/axe-check.js
Normal file
@@ -0,0 +1,145 @@
|
||||
class QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
this.axeResult = axeResult;
|
||||
this.options = options;
|
||||
}
|
||||
|
||||
report() {
|
||||
throw new Error("report() is an abstract method");
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeJsonReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
report() {
|
||||
console.log(JSON.stringify(this.axeResult, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeConsoleReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
report() {
|
||||
for (const violation of this.axeResult.violations) {
|
||||
console.log(violation.description);
|
||||
for (const node of violation.nodes) {
|
||||
for (const target of node.target) {
|
||||
console.log(target);
|
||||
console.log(document.querySelector(target));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class QuartoAxeDocumentReporter extends QuartoAxeReporter {
|
||||
constructor(axeResult, options) {
|
||||
super(axeResult, options);
|
||||
}
|
||||
|
||||
createViolationElement(violation) {
|
||||
const violationElement = document.createElement("div");
|
||||
|
||||
const descriptionElement = document.createElement("div");
|
||||
descriptionElement.className = "quarto-axe-violation-description";
|
||||
descriptionElement.innerText = `${violation.impact.replace(/^[a-z]/, match => match.toLocaleUpperCase())}: ${violation.description}`;
|
||||
violationElement.appendChild(descriptionElement);
|
||||
|
||||
const helpElement = document.createElement("div");
|
||||
helpElement.className = "quarto-axe-violation-help";
|
||||
helpElement.innerText = violation.help;
|
||||
violationElement.appendChild(helpElement);
|
||||
|
||||
const nodesElement = document.createElement("div");
|
||||
nodesElement.className = "quarto-axe-violation-nodes";
|
||||
violationElement.appendChild(nodesElement);
|
||||
const nodeElement = document.createElement("div");
|
||||
nodeElement.className = "quarto-axe-violation-selector";
|
||||
for (const node of violation.nodes) {
|
||||
for (const target of node.target) {
|
||||
const targetElement = document.createElement("span");
|
||||
targetElement.className = "quarto-axe-violation-target";
|
||||
targetElement.innerText = target;
|
||||
nodeElement.appendChild(targetElement);
|
||||
nodeElement.addEventListener("mouseenter", () => {
|
||||
const element = document.querySelector(target);
|
||||
if (element) {
|
||||
element.scrollIntoView({ behavior: "smooth", block: "center" });
|
||||
element.classList.add("quarto-axe-hover-highlight");
|
||||
setTimeout(() => {
|
||||
element.style.border = "";
|
||||
}, 2000);
|
||||
}
|
||||
});
|
||||
nodeElement.addEventListener("mouseleave", () => {
|
||||
const element = document.querySelector(target);
|
||||
if (element) {
|
||||
element.classList.remove("quarto-axe-hover-highlight");
|
||||
}
|
||||
});
|
||||
nodeElement.addEventListener("click", () => {
|
||||
console.log(document.querySelector(target));
|
||||
});
|
||||
nodeElement.appendChild(targetElement);
|
||||
}
|
||||
nodesElement.appendChild(nodeElement);
|
||||
}
|
||||
return violationElement;
|
||||
}
|
||||
|
||||
report() {
|
||||
const violations = this.axeResult.violations;
|
||||
const reportElement = document.createElement("div");
|
||||
reportElement.className = "quarto-axe-report";
|
||||
if (violations.length === 0) {
|
||||
const noViolationsElement = document.createElement("div");
|
||||
noViolationsElement.className = "quarto-axe-no-violations";
|
||||
noViolationsElement.innerText = "No axe-core violations found.";
|
||||
reportElement.appendChild(noViolationsElement);
|
||||
}
|
||||
violations.forEach((violation) => {
|
||||
reportElement.appendChild(this.createViolationElement(violation));
|
||||
});
|
||||
document.querySelector("main").appendChild(reportElement);
|
||||
}
|
||||
}
|
||||
|
||||
const reporters = {
|
||||
json: QuartoAxeJsonReporter,
|
||||
console: QuartoAxeConsoleReporter,
|
||||
document: QuartoAxeDocumentReporter,
|
||||
};
|
||||
|
||||
class QuartoAxeChecker {
|
||||
constructor(opts) {
|
||||
this.options = opts;
|
||||
}
|
||||
async init() {
|
||||
const axe = (await import("https://cdn.skypack.dev/pin/axe-core@v4.10.3-aVOFXWsJaCpVrtv89pCa/mode=imports,min/optimized/axe-core.js")).default;
|
||||
const result = await axe.run({
|
||||
exclude: [
|
||||
// https://github.com/microsoft/tabster/issues/288
|
||||
// MS has claimed they won't fix this, so we need to add an exclusion to
|
||||
// all tabster elements
|
||||
"[data-tabster-dummy]"
|
||||
],
|
||||
preload: { assets: ['cssom'], timeout: 50000 }
|
||||
});
|
||||
const reporter = this.options === true ? new QuartoAxeConsoleReporter(result) : new reporters[this.options.output](result, this.options);
|
||||
reporter.report();
|
||||
}
|
||||
}
|
||||
|
||||
export async function init() {
|
||||
const opts = document.querySelector("#quarto-axe-checker-options");
|
||||
if (opts) {
|
||||
const jsonOptions = JSON.parse(atob(opts.textContent));
|
||||
const checker = new QuartoAxeChecker(jsonOptions);
|
||||
await checker.init();
|
||||
}
|
||||
}
|
||||
6
Readme_files/libs/quarto-html/popper.min.js
vendored
Normal file
@@ -0,0 +1,236 @@
|
||||
/* quarto syntax highlight colors */
|
||||
:root {
|
||||
--quarto-hl-ot-color: #003B4F;
|
||||
--quarto-hl-at-color: #657422;
|
||||
--quarto-hl-ss-color: #20794D;
|
||||
--quarto-hl-an-color: #5E5E5E;
|
||||
--quarto-hl-fu-color: #4758AB;
|
||||
--quarto-hl-st-color: #20794D;
|
||||
--quarto-hl-cf-color: #003B4F;
|
||||
--quarto-hl-op-color: #5E5E5E;
|
||||
--quarto-hl-er-color: #AD0000;
|
||||
--quarto-hl-bn-color: #AD0000;
|
||||
--quarto-hl-al-color: #AD0000;
|
||||
--quarto-hl-va-color: #111111;
|
||||
--quarto-hl-bu-color: inherit;
|
||||
--quarto-hl-ex-color: inherit;
|
||||
--quarto-hl-pp-color: #AD0000;
|
||||
--quarto-hl-in-color: #5E5E5E;
|
||||
--quarto-hl-vs-color: #20794D;
|
||||
--quarto-hl-wa-color: #5E5E5E;
|
||||
--quarto-hl-do-color: #5E5E5E;
|
||||
--quarto-hl-im-color: #00769E;
|
||||
--quarto-hl-ch-color: #20794D;
|
||||
--quarto-hl-dt-color: #AD0000;
|
||||
--quarto-hl-fl-color: #AD0000;
|
||||
--quarto-hl-co-color: #5E5E5E;
|
||||
--quarto-hl-cv-color: #5E5E5E;
|
||||
--quarto-hl-cn-color: #8f5902;
|
||||
--quarto-hl-sc-color: #5E5E5E;
|
||||
--quarto-hl-dv-color: #AD0000;
|
||||
--quarto-hl-kw-color: #003B4F;
|
||||
}
|
||||
|
||||
/* other quarto variables */
|
||||
:root {
|
||||
--quarto-font-monospace: SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
|
||||
}
|
||||
|
||||
/* syntax highlight based on Pandoc's rules */
|
||||
pre > code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
code.sourceCode > span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
div.sourceCode,
|
||||
div.sourceCode pre.sourceCode {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
/* Normal */
|
||||
code span {
|
||||
color: #003B4F;
|
||||
}
|
||||
|
||||
/* Alert */
|
||||
code span.al {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Annotation */
|
||||
code span.an {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Attribute */
|
||||
code span.at {
|
||||
color: #657422;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* BaseN */
|
||||
code span.bn {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* BuiltIn */
|
||||
code span.bu {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* ControlFlow */
|
||||
code span.cf {
|
||||
color: #003B4F;
|
||||
font-weight: bold;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Char */
|
||||
code span.ch {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Constant */
|
||||
code span.cn {
|
||||
color: #8f5902;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Comment */
|
||||
code span.co {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* CommentVar */
|
||||
code span.cv {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* Documentation */
|
||||
code span.do {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
/* DataType */
|
||||
code span.dt {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* DecVal */
|
||||
code span.dv {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Error */
|
||||
code span.er {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Extension */
|
||||
code span.ex {
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Float */
|
||||
code span.fl {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Function */
|
||||
code span.fu {
|
||||
color: #4758AB;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Import */
|
||||
code span.im {
|
||||
color: #00769E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Information */
|
||||
code span.in {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Keyword */
|
||||
code span.kw {
|
||||
color: #003B4F;
|
||||
font-weight: bold;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Operator */
|
||||
code span.op {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Other */
|
||||
code span.ot {
|
||||
color: #003B4F;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Preprocessor */
|
||||
code span.pp {
|
||||
color: #AD0000;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* SpecialChar */
|
||||
code span.sc {
|
||||
color: #5E5E5E;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* SpecialString */
|
||||
code span.ss {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* String */
|
||||
code span.st {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Variable */
|
||||
code span.va {
|
||||
color: #111111;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* VerbatimString */
|
||||
code span.vs {
|
||||
color: #20794D;
|
||||
font-style: inherit;
|
||||
}
|
||||
|
||||
/* Warning */
|
||||
code span.wa {
|
||||
color: #5E5E5E;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.prevent-inlining {
|
||||
content: "</";
|
||||
}
|
||||
|
||||
/*# sourceMappingURL=2dce1cc6c82594539e1579de68416b47.css.map */
|
||||
847
Readme_files/libs/quarto-html/quarto.js
Normal file
@@ -0,0 +1,847 @@
|
||||
import * as tabsets from "./tabsets/tabsets.js";
|
||||
import * as axe from "./axe/axe-check.js";
|
||||
|
||||
const sectionChanged = new CustomEvent("quarto-sectionChanged", {
|
||||
detail: {},
|
||||
bubbles: true,
|
||||
cancelable: false,
|
||||
composed: false,
|
||||
});
|
||||
|
||||
const layoutMarginEls = () => {
|
||||
// Find any conflicting margin elements and add margins to the
|
||||
// top to prevent overlap
|
||||
const marginChildren = window.document.querySelectorAll(
|
||||
".column-margin.column-container > *, .margin-caption, .aside"
|
||||
);
|
||||
|
||||
let lastBottom = 0;
|
||||
for (const marginChild of marginChildren) {
|
||||
if (marginChild.offsetParent !== null) {
|
||||
// clear the top margin so we recompute it
|
||||
marginChild.style.marginTop = null;
|
||||
const top = marginChild.getBoundingClientRect().top + window.scrollY;
|
||||
if (top < lastBottom) {
|
||||
const marginChildStyle = window.getComputedStyle(marginChild);
|
||||
const marginBottom = parseFloat(marginChildStyle["marginBottom"]);
|
||||
const margin = lastBottom - top + marginBottom;
|
||||
marginChild.style.marginTop = `${margin}px`;
|
||||
}
|
||||
const styles = window.getComputedStyle(marginChild);
|
||||
const marginTop = parseFloat(styles["marginTop"]);
|
||||
lastBottom = top + marginChild.getBoundingClientRect().height + marginTop;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
window.document.addEventListener("DOMContentLoaded", function (_event) {
|
||||
// Recompute the position of margin elements anytime the body size changes
|
||||
if (window.ResizeObserver) {
|
||||
const resizeObserver = new window.ResizeObserver(
|
||||
throttle(() => {
|
||||
layoutMarginEls();
|
||||
if (
|
||||
window.document.body.getBoundingClientRect().width < 990 &&
|
||||
isReaderMode()
|
||||
) {
|
||||
quartoToggleReader();
|
||||
}
|
||||
}, 50)
|
||||
);
|
||||
resizeObserver.observe(window.document.body);
|
||||
}
|
||||
|
||||
const tocEl = window.document.querySelector('nav.toc-active[role="doc-toc"]');
|
||||
const sidebarEl = window.document.getElementById("quarto-sidebar");
|
||||
const leftTocEl = window.document.getElementById("quarto-sidebar-toc-left");
|
||||
const marginSidebarEl = window.document.getElementById(
|
||||
"quarto-margin-sidebar"
|
||||
);
|
||||
// function to determine whether the element has a previous sibling that is active
|
||||
const prevSiblingIsActiveLink = (el) => {
|
||||
const sibling = el.previousElementSibling;
|
||||
if (sibling && sibling.tagName === "A") {
|
||||
return sibling.classList.contains("active");
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
// dispatch for htmlwidgets
|
||||
// they use slideenter event to trigger resize
|
||||
function fireSlideEnter() {
|
||||
const event = window.document.createEvent("Event");
|
||||
event.initEvent("slideenter", true, true);
|
||||
window.document.dispatchEvent(event);
|
||||
}
|
||||
|
||||
const tabs = window.document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
tabs.forEach((tab) => {
|
||||
tab.addEventListener("shown.bs.tab", fireSlideEnter);
|
||||
});
|
||||
|
||||
// dispatch for shiny
|
||||
// they use BS shown and hidden events to trigger rendering
|
||||
function distpatchShinyEvents(previous, current) {
|
||||
if (window.jQuery) {
|
||||
if (previous) {
|
||||
window.jQuery(previous).trigger("hidden");
|
||||
}
|
||||
if (current) {
|
||||
window.jQuery(current).trigger("shown");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// tabby.js listener: Trigger event for htmlwidget and shiny
|
||||
document.addEventListener(
|
||||
"tabby",
|
||||
function (event) {
|
||||
fireSlideEnter();
|
||||
distpatchShinyEvents(event.detail.previousTab, event.detail.tab);
|
||||
},
|
||||
false
|
||||
);
|
||||
|
||||
// Track scrolling and mark TOC links as active
|
||||
// get table of contents and sidebar (bail if we don't have at least one)
|
||||
const tocLinks = tocEl
|
||||
? [...tocEl.querySelectorAll("a[data-scroll-target]")]
|
||||
: [];
|
||||
const makeActive = (link) => tocLinks[link].classList.add("active");
|
||||
const removeActive = (link) => tocLinks[link].classList.remove("active");
|
||||
const removeAllActive = () =>
|
||||
[...Array(tocLinks.length).keys()].forEach((link) => removeActive(link));
|
||||
|
||||
// activate the anchor for a section associated with this TOC entry
|
||||
tocLinks.forEach((link) => {
|
||||
link.addEventListener("click", () => {
|
||||
if (link.href.indexOf("#") !== -1) {
|
||||
const anchor = link.href.split("#")[1];
|
||||
const heading = window.document.querySelector(
|
||||
`[data-anchor-id="${anchor}"]`
|
||||
);
|
||||
if (heading) {
|
||||
// Add the class
|
||||
heading.classList.add("reveal-anchorjs-link");
|
||||
|
||||
// function to show the anchor
|
||||
const handleMouseout = () => {
|
||||
heading.classList.remove("reveal-anchorjs-link");
|
||||
heading.removeEventListener("mouseout", handleMouseout);
|
||||
};
|
||||
|
||||
// add a function to clear the anchor when the user mouses out of it
|
||||
heading.addEventListener("mouseout", handleMouseout);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
const sections = tocLinks.map((link) => {
|
||||
const target = link.getAttribute("data-scroll-target");
|
||||
if (target.startsWith("#")) {
|
||||
return window.document.getElementById(decodeURI(`${target.slice(1)}`));
|
||||
} else {
|
||||
return window.document.querySelector(decodeURI(`${target}`));
|
||||
}
|
||||
});
|
||||
|
||||
const sectionMargin = 200;
|
||||
let currentActive = 0;
|
||||
// track whether we've initialized state the first time
|
||||
let init = false;
|
||||
|
||||
const updateActiveLink = () => {
|
||||
// The index from bottom to top (e.g. reversed list)
|
||||
let sectionIndex = -1;
|
||||
if (
|
||||
window.innerHeight + window.pageYOffset >=
|
||||
window.document.body.offsetHeight
|
||||
) {
|
||||
// This is the no-scroll case where last section should be the active one
|
||||
sectionIndex = 0;
|
||||
} else {
|
||||
// This finds the last section visible on screen that should be made active
|
||||
sectionIndex = [...sections].reverse().findIndex((section) => {
|
||||
if (section) {
|
||||
return window.pageYOffset >= section.offsetTop - sectionMargin;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
});
|
||||
}
|
||||
if (sectionIndex > -1) {
|
||||
const current = sections.length - sectionIndex - 1;
|
||||
if (current !== currentActive) {
|
||||
removeAllActive();
|
||||
currentActive = current;
|
||||
makeActive(current);
|
||||
if (init) {
|
||||
window.dispatchEvent(sectionChanged);
|
||||
}
|
||||
init = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const inHiddenRegion = (top, bottom, hiddenRegions) => {
|
||||
for (const region of hiddenRegions) {
|
||||
if (top <= region.bottom && bottom >= region.top) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
const categorySelector = "header.quarto-title-block .quarto-category";
|
||||
const activateCategories = (href) => {
|
||||
// Find any categories
|
||||
// Surround them with a link pointing back to:
|
||||
// #category=Authoring
|
||||
try {
|
||||
const categoryEls = window.document.querySelectorAll(categorySelector);
|
||||
for (const categoryEl of categoryEls) {
|
||||
const categoryText = categoryEl.textContent;
|
||||
if (categoryText) {
|
||||
const link = `${href}#category=${encodeURIComponent(categoryText)}`;
|
||||
const linkEl = window.document.createElement("a");
|
||||
linkEl.setAttribute("href", link);
|
||||
for (const child of categoryEl.childNodes) {
|
||||
linkEl.append(child);
|
||||
}
|
||||
categoryEl.appendChild(linkEl);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
// Ignore errors
|
||||
}
|
||||
};
|
||||
function hasTitleCategories() {
|
||||
return window.document.querySelector(categorySelector) !== null;
|
||||
}
|
||||
|
||||
function offsetRelativeUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
return offset ? offset + url : url;
|
||||
}
|
||||
|
||||
function offsetAbsoluteUrl(url) {
|
||||
const offset = getMeta("quarto:offset");
|
||||
const baseUrl = new URL(offset, window.location);
|
||||
|
||||
const projRelativeUrl = url.replace(baseUrl, "");
|
||||
if (projRelativeUrl.startsWith("/")) {
|
||||
return projRelativeUrl;
|
||||
} else {
|
||||
return "/" + projRelativeUrl;
|
||||
}
|
||||
}
|
||||
|
||||
// read a meta tag value
|
||||
function getMeta(metaName) {
|
||||
const metas = window.document.getElementsByTagName("meta");
|
||||
for (let i = 0; i < metas.length; i++) {
|
||||
if (metas[i].getAttribute("name") === metaName) {
|
||||
return metas[i].getAttribute("content");
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
async function findAndActivateCategories() {
|
||||
// Categories search with listing only use path without query
|
||||
const currentPagePath = offsetAbsoluteUrl(
|
||||
window.location.origin + window.location.pathname
|
||||
);
|
||||
const response = await fetch(offsetRelativeUrl("listings.json"));
|
||||
if (response.status == 200) {
|
||||
return response.json().then(function (listingPaths) {
|
||||
const listingHrefs = [];
|
||||
for (const listingPath of listingPaths) {
|
||||
const pathWithoutLeadingSlash = listingPath.listing.substring(1);
|
||||
for (const item of listingPath.items) {
|
||||
const encodedItem = encodeURI(item);
|
||||
if (
|
||||
encodedItem === currentPagePath ||
|
||||
encodedItem === currentPagePath + "index.html"
|
||||
) {
|
||||
// Resolve this path against the offset to be sure
|
||||
// we already are using the correct path to the listing
|
||||
// (this adjusts the listing urls to be rooted against
|
||||
// whatever root the page is actually running against)
|
||||
const relative = offsetRelativeUrl(pathWithoutLeadingSlash);
|
||||
const baseUrl = window.location;
|
||||
const resolvedPath = new URL(relative, baseUrl);
|
||||
listingHrefs.push(resolvedPath.pathname);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const nearestListing = findNearestParentListing(
|
||||
offsetAbsoluteUrl(window.location.pathname),
|
||||
listingHrefs
|
||||
);
|
||||
if (nearestListing) {
|
||||
activateCategories(nearestListing);
|
||||
} else {
|
||||
// See if the referrer is a listing page for this item
|
||||
const referredRelativePath = offsetAbsoluteUrl(document.referrer);
|
||||
const referrerListing = listingHrefs.find((listingHref) => {
|
||||
const isListingReferrer =
|
||||
listingHref === referredRelativePath ||
|
||||
listingHref === referredRelativePath + "index.html";
|
||||
return isListingReferrer;
|
||||
});
|
||||
|
||||
if (referrerListing) {
|
||||
// Try to use the referrer if possible
|
||||
activateCategories(referrerListing);
|
||||
} else if (listingHrefs.length > 0) {
|
||||
// Otherwise, just fall back to the first listing
|
||||
activateCategories(listingHrefs[0]);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
if (hasTitleCategories()) {
|
||||
findAndActivateCategories();
|
||||
}
|
||||
|
||||
const findNearestParentListing = (href, listingHrefs) => {
|
||||
if (!href || !listingHrefs) {
|
||||
return undefined;
|
||||
}
|
||||
// Look up the tree for a nearby linting and use that if we find one
|
||||
const relativeParts = href.substring(1).split("/");
|
||||
while (relativeParts.length > 0) {
|
||||
const path = relativeParts.join("/");
|
||||
for (const listingHref of listingHrefs) {
|
||||
if (listingHref.startsWith(path)) {
|
||||
return listingHref;
|
||||
}
|
||||
}
|
||||
relativeParts.pop();
|
||||
}
|
||||
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const manageSidebarVisiblity = (el, placeholderDescriptor) => {
|
||||
let isVisible = true;
|
||||
let elRect;
|
||||
|
||||
return (hiddenRegions) => {
|
||||
if (el === null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Find the last element of the TOC
|
||||
const lastChildEl = el.lastElementChild;
|
||||
|
||||
if (lastChildEl) {
|
||||
// Converts the sidebar to a menu
|
||||
const convertToMenu = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 0;
|
||||
child.style.overflow = "hidden";
|
||||
child.style.pointerEvents = "none";
|
||||
}
|
||||
|
||||
nexttick(() => {
|
||||
const toggleContainer = window.document.createElement("div");
|
||||
toggleContainer.style.width = "100%";
|
||||
toggleContainer.classList.add("zindex-over-content");
|
||||
toggleContainer.classList.add("quarto-sidebar-toggle");
|
||||
toggleContainer.classList.add("headroom-target"); // Marks this to be managed by headeroom
|
||||
toggleContainer.id = placeholderDescriptor.id;
|
||||
toggleContainer.style.position = "fixed";
|
||||
|
||||
const toggleIcon = window.document.createElement("i");
|
||||
toggleIcon.classList.add("quarto-sidebar-toggle-icon");
|
||||
toggleIcon.classList.add("bi");
|
||||
toggleIcon.classList.add("bi-caret-down-fill");
|
||||
|
||||
const toggleTitle = window.document.createElement("div");
|
||||
const titleEl = window.document.body.querySelector(
|
||||
placeholderDescriptor.titleSelector
|
||||
);
|
||||
if (titleEl) {
|
||||
toggleTitle.append(
|
||||
titleEl.textContent || titleEl.innerText,
|
||||
toggleIcon
|
||||
);
|
||||
}
|
||||
toggleTitle.classList.add("zindex-over-content");
|
||||
toggleTitle.classList.add("quarto-sidebar-toggle-title");
|
||||
toggleContainer.append(toggleTitle);
|
||||
|
||||
const toggleContents = window.document.createElement("div");
|
||||
toggleContents.classList = el.classList;
|
||||
toggleContents.classList.add("zindex-over-content");
|
||||
toggleContents.classList.add("quarto-sidebar-toggle-contents");
|
||||
for (const child of el.children) {
|
||||
if (child.id === "toc-title") {
|
||||
continue;
|
||||
}
|
||||
|
||||
const clone = child.cloneNode(true);
|
||||
clone.style.opacity = 1;
|
||||
clone.style.pointerEvents = null;
|
||||
clone.style.display = null;
|
||||
toggleContents.append(clone);
|
||||
}
|
||||
toggleContents.style.height = "0px";
|
||||
const positionToggle = () => {
|
||||
// position the element (top left of parent, same width as parent)
|
||||
if (!elRect) {
|
||||
elRect = el.getBoundingClientRect();
|
||||
}
|
||||
toggleContainer.style.left = `${elRect.left}px`;
|
||||
toggleContainer.style.top = `${elRect.top}px`;
|
||||
toggleContainer.style.width = `${elRect.width}px`;
|
||||
};
|
||||
positionToggle();
|
||||
|
||||
toggleContainer.append(toggleContents);
|
||||
el.parentElement.prepend(toggleContainer);
|
||||
|
||||
// Process clicks
|
||||
let tocShowing = false;
|
||||
// Allow the caller to control whether this is dismissed
|
||||
// when it is clicked (e.g. sidebar navigation supports
|
||||
// opening and closing the nav tree, so don't dismiss on click)
|
||||
const clickEl = placeholderDescriptor.dismissOnClick
|
||||
? toggleContainer
|
||||
: toggleTitle;
|
||||
|
||||
const closeToggle = () => {
|
||||
if (tocShowing) {
|
||||
toggleContainer.classList.remove("expanded");
|
||||
toggleContents.style.height = "0px";
|
||||
tocShowing = false;
|
||||
}
|
||||
};
|
||||
|
||||
// Get rid of any expanded toggle if the user scrolls
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
closeToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
// Handle positioning of the toggle
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
elRect = undefined;
|
||||
positionToggle();
|
||||
}, 50)
|
||||
);
|
||||
|
||||
window.addEventListener("quarto-hrChanged", () => {
|
||||
elRect = undefined;
|
||||
});
|
||||
|
||||
// Process the click
|
||||
clickEl.onclick = () => {
|
||||
if (!tocShowing) {
|
||||
toggleContainer.classList.add("expanded");
|
||||
toggleContents.style.height = null;
|
||||
tocShowing = true;
|
||||
} else {
|
||||
closeToggle();
|
||||
}
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
// Converts a sidebar from a menu back to a sidebar
|
||||
const convertToSidebar = () => {
|
||||
for (const child of el.children) {
|
||||
child.style.opacity = 1;
|
||||
child.style.overflow = null;
|
||||
child.style.pointerEvents = null;
|
||||
}
|
||||
|
||||
const placeholderEl = window.document.getElementById(
|
||||
placeholderDescriptor.id
|
||||
);
|
||||
if (placeholderEl) {
|
||||
placeholderEl.remove();
|
||||
}
|
||||
|
||||
el.classList.remove("rollup");
|
||||
};
|
||||
|
||||
if (isReaderMode()) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
} else {
|
||||
// Find the top and bottom o the element that is being managed
|
||||
const elTop = el.offsetTop;
|
||||
const elBottom =
|
||||
elTop + lastChildEl.offsetTop + lastChildEl.offsetHeight;
|
||||
|
||||
if (!isVisible) {
|
||||
// If the element is current not visible reveal if there are
|
||||
// no conflicts with overlay regions
|
||||
if (!inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToSidebar();
|
||||
isVisible = true;
|
||||
}
|
||||
} else {
|
||||
// If the element is visible, hide it if it conflicts with overlay regions
|
||||
// and insert a placeholder toggle (or if we're in reader mode)
|
||||
if (inHiddenRegion(elTop, elBottom, hiddenRegions)) {
|
||||
convertToMenu();
|
||||
isVisible = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
const tabEls = document.querySelectorAll('a[data-bs-toggle="tab"]');
|
||||
for (const tabEl of tabEls) {
|
||||
const id = tabEl.getAttribute("data-bs-target");
|
||||
if (id) {
|
||||
const columnEl = document.querySelector(
|
||||
`${id} .column-margin, .tabset-margin-content`
|
||||
);
|
||||
if (columnEl)
|
||||
tabEl.addEventListener("shown.bs.tab", function (event) {
|
||||
const el = event.srcElement;
|
||||
if (el) {
|
||||
const visibleCls = `${el.id}-margin-content`;
|
||||
// walk up until we find a parent tabset
|
||||
let panelTabsetEl = el.parentElement;
|
||||
while (panelTabsetEl) {
|
||||
if (panelTabsetEl.classList.contains("panel-tabset")) {
|
||||
break;
|
||||
}
|
||||
panelTabsetEl = panelTabsetEl.parentElement;
|
||||
}
|
||||
|
||||
if (panelTabsetEl) {
|
||||
const prevSib = panelTabsetEl.previousElementSibling;
|
||||
if (
|
||||
prevSib &&
|
||||
prevSib.classList.contains("tabset-margin-container")
|
||||
) {
|
||||
const childNodes = prevSib.querySelectorAll(
|
||||
".tabset-margin-content"
|
||||
);
|
||||
for (const childEl of childNodes) {
|
||||
if (childEl.classList.contains(visibleCls)) {
|
||||
childEl.classList.remove("collapse");
|
||||
} else {
|
||||
childEl.classList.add("collapse");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
layoutMarginEls();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Manage the visibility of the toc and the sidebar
|
||||
const marginScrollVisibility = manageSidebarVisiblity(marginSidebarEl, {
|
||||
id: "quarto-toc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
const sidebarScrollVisiblity = manageSidebarVisiblity(sidebarEl, {
|
||||
id: "quarto-sidebarnav-toggle",
|
||||
titleSelector: ".title",
|
||||
dismissOnClick: false,
|
||||
});
|
||||
let tocLeftScrollVisibility;
|
||||
if (leftTocEl) {
|
||||
tocLeftScrollVisibility = manageSidebarVisiblity(leftTocEl, {
|
||||
id: "quarto-lefttoc-toggle",
|
||||
titleSelector: "#toc-title",
|
||||
dismissOnClick: true,
|
||||
});
|
||||
}
|
||||
|
||||
// Find the first element that uses formatting in special columns
|
||||
const conflictingEls = window.document.body.querySelectorAll(
|
||||
'[class^="column-"], [class*=" column-"], aside, [class*="margin-caption"], [class*=" margin-caption"], [class*="margin-ref"], [class*=" margin-ref"]'
|
||||
);
|
||||
|
||||
// Filter all the possibly conflicting elements into ones
|
||||
// the do conflict on the left or ride side
|
||||
const arrConflictingEls = Array.from(conflictingEls);
|
||||
const leftSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return false;
|
||||
}
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("right") &&
|
||||
!className.endsWith("container") &&
|
||||
className !== "column-margin"
|
||||
);
|
||||
});
|
||||
});
|
||||
const rightSideConflictEls = arrConflictingEls.filter((el) => {
|
||||
if (el.tagName === "ASIDE") {
|
||||
return true;
|
||||
}
|
||||
|
||||
const hasMarginCaption = Array.from(el.classList).find((className) => {
|
||||
return className == "margin-caption";
|
||||
});
|
||||
if (hasMarginCaption) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return Array.from(el.classList).find((className) => {
|
||||
return (
|
||||
className !== "column-body" &&
|
||||
!className.endsWith("container") &&
|
||||
className.startsWith("column-") &&
|
||||
!className.endsWith("left")
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
const kOverlapPaddingSize = 10;
|
||||
function toRegions(els) {
|
||||
return els.map((el) => {
|
||||
const boundRect = el.getBoundingClientRect();
|
||||
const top =
|
||||
boundRect.top +
|
||||
document.documentElement.scrollTop -
|
||||
kOverlapPaddingSize;
|
||||
return {
|
||||
top,
|
||||
bottom: top + el.scrollHeight + 2 * kOverlapPaddingSize,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
let hasObserved = false;
|
||||
const visibleItemObserver = (els) => {
|
||||
let visibleElements = [...els];
|
||||
const intersectionObserver = new IntersectionObserver(
|
||||
(entries, _observer) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
if (visibleElements.indexOf(entry.target) === -1) {
|
||||
visibleElements.push(entry.target);
|
||||
}
|
||||
} else {
|
||||
visibleElements = visibleElements.filter((visibleEntry) => {
|
||||
return visibleEntry !== entry;
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
if (!hasObserved) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
hasObserved = true;
|
||||
},
|
||||
{}
|
||||
);
|
||||
els.forEach((el) => {
|
||||
intersectionObserver.observe(el);
|
||||
});
|
||||
|
||||
return {
|
||||
getVisibleEntries: () => {
|
||||
return visibleElements;
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
const rightElementObserver = visibleItemObserver(rightSideConflictEls);
|
||||
const leftElementObserver = visibleItemObserver(leftSideConflictEls);
|
||||
|
||||
const hideOverlappedSidebars = () => {
|
||||
marginScrollVisibility(toRegions(rightElementObserver.getVisibleEntries()));
|
||||
sidebarScrollVisiblity(toRegions(leftElementObserver.getVisibleEntries()));
|
||||
if (tocLeftScrollVisibility) {
|
||||
tocLeftScrollVisibility(
|
||||
toRegions(leftElementObserver.getVisibleEntries())
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
window.quartoToggleReader = () => {
|
||||
// Applies a slow class (or removes it)
|
||||
// to update the transition speed
|
||||
const slowTransition = (slow) => {
|
||||
const manageTransition = (id, slow) => {
|
||||
const el = document.getElementById(id);
|
||||
if (el) {
|
||||
if (slow) {
|
||||
el.classList.add("slow");
|
||||
} else {
|
||||
el.classList.remove("slow");
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
manageTransition("TOC", slow);
|
||||
manageTransition("quarto-sidebar", slow);
|
||||
};
|
||||
const readerMode = !isReaderMode();
|
||||
setReaderModeValue(readerMode);
|
||||
|
||||
// If we're entering reader mode, slow the transition
|
||||
if (readerMode) {
|
||||
slowTransition(readerMode);
|
||||
}
|
||||
highlightReaderToggle(readerMode);
|
||||
hideOverlappedSidebars();
|
||||
|
||||
// If we're exiting reader mode, restore the non-slow transition
|
||||
if (!readerMode) {
|
||||
slowTransition(!readerMode);
|
||||
}
|
||||
};
|
||||
|
||||
const highlightReaderToggle = (readerMode) => {
|
||||
const els = document.querySelectorAll(".quarto-reader-toggle");
|
||||
if (els) {
|
||||
els.forEach((el) => {
|
||||
if (readerMode) {
|
||||
el.classList.add("reader");
|
||||
} else {
|
||||
el.classList.remove("reader");
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
const setReaderModeValue = (val) => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
window.localStorage.setItem("quarto-reader-mode", val);
|
||||
} else {
|
||||
localReaderMode = val;
|
||||
}
|
||||
};
|
||||
|
||||
const isReaderMode = () => {
|
||||
if (window.location.protocol !== "file:") {
|
||||
return window.localStorage.getItem("quarto-reader-mode") === "true";
|
||||
} else {
|
||||
return localReaderMode;
|
||||
}
|
||||
};
|
||||
let localReaderMode = null;
|
||||
|
||||
const tocOpenDepthStr = tocEl?.getAttribute("data-toc-expanded");
|
||||
const tocOpenDepth = tocOpenDepthStr ? Number(tocOpenDepthStr) : 1;
|
||||
|
||||
// Walk the TOC and collapse/expand nodes
|
||||
// Nodes are expanded if:
|
||||
// - they are top level
|
||||
// - they have children that are 'active' links
|
||||
// - they are directly below an link that is 'active'
|
||||
const walk = (el, depth) => {
|
||||
// Tick depth when we enter a UL
|
||||
if (el.tagName === "UL") {
|
||||
depth = depth + 1;
|
||||
}
|
||||
|
||||
// It this is active link
|
||||
let isActiveNode = false;
|
||||
if (el.tagName === "A" && el.classList.contains("active")) {
|
||||
isActiveNode = true;
|
||||
}
|
||||
|
||||
// See if there is an active child to this element
|
||||
let hasActiveChild = false;
|
||||
for (const child of el.children) {
|
||||
hasActiveChild = walk(child, depth) || hasActiveChild;
|
||||
}
|
||||
|
||||
// Process the collapse state if this is an UL
|
||||
if (el.tagName === "UL") {
|
||||
if (tocOpenDepth === -1 && depth > 1) {
|
||||
// toc-expand: false
|
||||
el.classList.add("collapse");
|
||||
} else if (
|
||||
depth <= tocOpenDepth ||
|
||||
hasActiveChild ||
|
||||
prevSiblingIsActiveLink(el)
|
||||
) {
|
||||
el.classList.remove("collapse");
|
||||
} else {
|
||||
el.classList.add("collapse");
|
||||
}
|
||||
|
||||
// untick depth when we leave a UL
|
||||
depth = depth - 1;
|
||||
}
|
||||
return hasActiveChild || isActiveNode;
|
||||
};
|
||||
|
||||
// walk the TOC and expand / collapse any items that should be shown
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
|
||||
// Throttle the scroll event and walk peridiocally
|
||||
window.document.addEventListener(
|
||||
"scroll",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 5)
|
||||
);
|
||||
window.addEventListener(
|
||||
"resize",
|
||||
throttle(() => {
|
||||
if (tocEl) {
|
||||
updateActiveLink();
|
||||
walk(tocEl, 0);
|
||||
}
|
||||
if (!isReaderMode()) {
|
||||
hideOverlappedSidebars();
|
||||
}
|
||||
}, 10)
|
||||
);
|
||||
hideOverlappedSidebars();
|
||||
highlightReaderToggle(isReaderMode());
|
||||
});
|
||||
|
||||
tabsets.init();
|
||||
axe.init();
|
||||
|
||||
function throttle(func, wait) {
|
||||
let waiting = false;
|
||||
return function () {
|
||||
if (!waiting) {
|
||||
func.apply(this, arguments);
|
||||
waiting = true;
|
||||
setTimeout(function () {
|
||||
waiting = false;
|
||||
}, wait);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function nexttick(func) {
|
||||
return setTimeout(func, 0);
|
||||
}
|
||||
95
Readme_files/libs/quarto-html/tabsets/tabsets.js
Normal file
@@ -0,0 +1,95 @@
|
||||
// grouped tabsets
|
||||
|
||||
export function init() {
|
||||
window.addEventListener("pageshow", (_event) => {
|
||||
function getTabSettings() {
|
||||
const data = localStorage.getItem("quarto-persistent-tabsets-data");
|
||||
if (!data) {
|
||||
localStorage.setItem("quarto-persistent-tabsets-data", "{}");
|
||||
return {};
|
||||
}
|
||||
if (data) {
|
||||
return JSON.parse(data);
|
||||
}
|
||||
}
|
||||
|
||||
function setTabSettings(data) {
|
||||
localStorage.setItem(
|
||||
"quarto-persistent-tabsets-data",
|
||||
JSON.stringify(data)
|
||||
);
|
||||
}
|
||||
|
||||
function setTabState(groupName, groupValue) {
|
||||
const data = getTabSettings();
|
||||
data[groupName] = groupValue;
|
||||
setTabSettings(data);
|
||||
}
|
||||
|
||||
function toggleTab(tab, active) {
|
||||
const tabPanelId = tab.getAttribute("aria-controls");
|
||||
const tabPanel = document.getElementById(tabPanelId);
|
||||
if (active) {
|
||||
tab.classList.add("active");
|
||||
tabPanel.classList.add("active");
|
||||
} else {
|
||||
tab.classList.remove("active");
|
||||
tabPanel.classList.remove("active");
|
||||
}
|
||||
}
|
||||
|
||||
function toggleAll(selectedGroup, selectorsToSync) {
|
||||
for (const [thisGroup, tabs] of Object.entries(selectorsToSync)) {
|
||||
const active = selectedGroup === thisGroup;
|
||||
for (const tab of tabs) {
|
||||
toggleTab(tab, active);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function findSelectorsToSyncByLanguage() {
|
||||
const result = {};
|
||||
const tabs = Array.from(
|
||||
document.querySelectorAll(`div[data-group] a[id^='tabset-']`)
|
||||
);
|
||||
for (const item of tabs) {
|
||||
const div = item.parentElement.parentElement.parentElement;
|
||||
const group = div.getAttribute("data-group");
|
||||
if (!result[group]) {
|
||||
result[group] = {};
|
||||
}
|
||||
const selectorsToSync = result[group];
|
||||
const value = item.innerHTML;
|
||||
if (!selectorsToSync[value]) {
|
||||
selectorsToSync[value] = [];
|
||||
}
|
||||
selectorsToSync[value].push(item);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function setupSelectorSync() {
|
||||
const selectorsToSync = findSelectorsToSyncByLanguage();
|
||||
Object.entries(selectorsToSync).forEach(([group, tabSetsByValue]) => {
|
||||
Object.entries(tabSetsByValue).forEach(([value, items]) => {
|
||||
items.forEach((item) => {
|
||||
item.addEventListener("click", (_event) => {
|
||||
setTabState(group, value);
|
||||
toggleAll(value, selectorsToSync[group]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
return selectorsToSync;
|
||||
}
|
||||
|
||||
const selectorsToSync = setupSelectorSync();
|
||||
for (const [group, selectedName] of Object.entries(getTabSettings())) {
|
||||
const selectors = selectorsToSync[group];
|
||||
// it's possible that stale state gives us empty selections, so we explicitly check here.
|
||||
if (selectors) {
|
||||
toggleAll(selectedName, selectors);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
1
Readme_files/libs/quarto-html/tippy.css
Normal file
@@ -0,0 +1 @@
|
||||
.tippy-box[data-animation=fade][data-state=hidden]{opacity:0}[data-tippy-root]{max-width:calc(100vw - 10px)}.tippy-box{position:relative;background-color:#333;color:#fff;border-radius:4px;font-size:14px;line-height:1.4;white-space:normal;outline:0;transition-property:transform,visibility,opacity}.tippy-box[data-placement^=top]>.tippy-arrow{bottom:0}.tippy-box[data-placement^=top]>.tippy-arrow:before{bottom:-7px;left:0;border-width:8px 8px 0;border-top-color:initial;transform-origin:center top}.tippy-box[data-placement^=bottom]>.tippy-arrow{top:0}.tippy-box[data-placement^=bottom]>.tippy-arrow:before{top:-7px;left:0;border-width:0 8px 8px;border-bottom-color:initial;transform-origin:center bottom}.tippy-box[data-placement^=left]>.tippy-arrow{right:0}.tippy-box[data-placement^=left]>.tippy-arrow:before{border-width:8px 0 8px 8px;border-left-color:initial;right:-7px;transform-origin:center left}.tippy-box[data-placement^=right]>.tippy-arrow{left:0}.tippy-box[data-placement^=right]>.tippy-arrow:before{left:-7px;border-width:8px 8px 8px 0;border-right-color:initial;transform-origin:center right}.tippy-box[data-inertia][data-state=visible]{transition-timing-function:cubic-bezier(.54,1.5,.38,1.11)}.tippy-arrow{width:16px;height:16px;color:#333}.tippy-arrow:before{content:"";position:absolute;border-color:transparent;border-style:solid}.tippy-content{position:relative;padding:5px 9px;z-index:1}
|
||||
2
Readme_files/libs/quarto-html/tippy.umd.min.js
vendored
Normal file
862
fish-primers.qmd
Normal file
@@ -0,0 +1,862 @@
|
||||
---
|
||||
title: "Designing Fish primers"
|
||||
format: revealjs
|
||||
editor: visual
|
||||
---
|
||||
|
||||
```{r setup, include=FALSE}
|
||||
library(knitr)
|
||||
```
|
||||
|
||||
# Preparing the data
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## What do we need ?
|
||||
|
||||
To design a new animal DNA metabarcode we download from the NCBI the following data
|
||||
|
||||
- The complete set of whole mitochondrial genomes
|
||||
- The NCBI taxonomy
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## We need also:
|
||||
|
||||
- a Unix computer: a Mac or a Linux box
|
||||
- A unix terminal window for typing commands
|
||||
- Installed on the computer
|
||||
- The OBITools --- <http://github.com/metabarcoding/obitools4>
|
||||
- ecoPrimers --- <http://metabarcoding.org/ecoprimers>
|
||||
- R --- <http://wwww.r-project.org>
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Downloading the mitochondrial genomes
|
||||
|
||||
We can use an internet browser and download the files from NCBI FTP website
|
||||
|
||||
{fig-align="center"}
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Downloading the mitochondrial genomes
|
||||
|
||||
We can use an internet browser and download the files from NCBI FTP website
|
||||
|
||||
or run the following command lines
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
curl 'https://ftp.ncbi.nlm.nih.gov/genomes/refseq/mitochondrion/mitochondrion.1.genomic.gbff.gz' \
|
||||
> mito.all.gb.gz
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
zless mito.all.gb.gz
|
||||
```
|
||||
|
||||
```
|
||||
LOCUS NW_009243181 45189 bp DNA linear CON 06-OCT-2014
|
||||
DEFINITION Fonticula alba strain ATCC 38817 mitochondrial scaffold
|
||||
supercont2.211, whole genome shotgun sequence.
|
||||
ACCESSION NW_009243181 NZ_AROH01000000
|
||||
VERSION NW_009243181.1
|
||||
DBLINK BioProject: PRJNA262900
|
||||
Assembly: GCF_000388065.1
|
||||
KEYWORDS WGS; RefSeq.
|
||||
SOURCE mitochondrion Fonticula alba
|
||||
ORGANISM Fonticula alba
|
||||
Eukaryota; Rotosphaerida; Fonticulaceae; Fonticula.
|
||||
REFERENCE 1 (bases 1 to 45189)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Downloading the complete taxonomy
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obitaxonomy --download-ncbi
|
||||
```
|
||||
|
||||
```
|
||||
INFO[0000] Number of workers set 16
|
||||
INFO[0000] Downloading NCBI Taxdump to ncbitaxo_20250211.tgz
|
||||
downloading 100% ████████████████████████████████████████| (66/66 MB, 5.1 MB/s)
|
||||
```
|
||||
|
||||
The NCBI taxonomy contains all the relationship between taxa. Each taxon is identified by a unique numerical id: `taxid`
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## The archive contains several files
|
||||
|
||||
file: `nodes.dmp`
|
||||
|
||||
```
|
||||
1 | 1 | no rank | | 8 | 0 | ...
|
||||
2 | 131567 | superkingdom | | 0 | 0 |
|
||||
6 | 335928 | genus | | 0 | 1 |
|
||||
7 | 6 | species | AC | 0 | 1 |
|
||||
9 | 32199 | species | BA | 0 |
|
||||
10 | 135621 | genus | | 0 |
|
||||
11 | 1707 | species | CG | 0 | 1 |
|
||||
13 | 203488 | genus | | 0 | 1 |
|
||||
14 | 13 | species | DT | 0 | 1 |
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## file: `names.dmp`
|
||||
|
||||
```
|
||||
1 | root | | scientific name |
|
||||
2 | Bacteria | Bacteria <prokaryote> | scientific name |
|
||||
2 | Monera | Monera <Bacteria> | in-part |
|
||||
2 | Procaryotae | Procaryotae <Bacteria> | in-part |
|
||||
2 | Prokaryota | Prokaryota <Bacteria> | in-part |
|
||||
2 | Prokaryotae | Prokaryotae <Bacteria> | in-part |
|
||||
2 | bacteria | bacteria <blast2> | blast name |
|
||||
2 | eubacteria | | genbank common name |
|
||||
2 | prokaryote | prokaryote <Bacteria> | in-part |
|
||||
...
|
||||
10 | Cellvibrio | | scientific name |
|
||||
11 | [Cellvibrio] gilvus | | scientific name |
|
||||
13 | Dictyoglomus | | scientific name |
|
||||
14 | Dictyoglomus thermophilum | | scientific name |
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Preparing the set of complete genomes
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obiconvert --skip-empty \
|
||||
--update-taxid \
|
||||
-t ncbitaxo_20250211.tgz \
|
||||
mito.all.gb.gz \
|
||||
> mito.all.fasta
|
||||
head -5 mito.all.fasta
|
||||
```
|
||||
|
||||
five first lines of the new `mito.all.fasta` file
|
||||
|
||||
```
|
||||
>NC_072933 {"definition":"Echinosophora koreensis mitochondrion, complete genome.","scientific_name":"mitochondrion Echinosophora koreensis","taxid":228658}
|
||||
ctttcgggtcggaaatagaagatctggattagatcccttctcgatagctttagtcagagc
|
||||
tcatccctcgaaaaagggagtagtgagatgagaaaagggtgactagaatacggaaattca
|
||||
actagtgaagtcagatccgggaattccactattgaagttatccgtcttaggcttcaagca
|
||||
agctatctttcaaggaagtcagtctaagccctaagccaagatctgctttttgccagtcaa
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## We want:
|
||||
|
||||
- annotate sequences by their species `taxid`
|
||||
- keep a single genome per species
|
||||
- extract only vertebrate genome
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Looking for the **Vertebrata**'s taxid
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obitaxonomy -t ncbitaxo_20250211.tgz \
|
||||
--fixed \
|
||||
'vertebrata'
|
||||
```
|
||||
|
||||
``` csv
|
||||
taxid,parent,taxonomic_rank,scientific_name
|
||||
taxon:1261581 [Vertebrata]@genus,taxon:2008651 [Polysiphonioideae]@subfamily,genus,Vertebrata
|
||||
taxon:7742 [Vertebrata]@clade,taxon:89593 [Craniata]@subphylum,clade,Vertebrata
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Looking for the **Vertebrata**'s taxid
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obitaxonomy -t ncbitaxo_20250211.tgz \
|
||||
--fixed \
|
||||
'vertebrata' \
|
||||
| csvlook
|
||||
```
|
||||
|
||||
``` csv
|
||||
| taxid | parent | taxonomic_rank | scientific_name |
|
||||
| -------------------------------- | ------------------------------------------- | -------------- | --------------- |
|
||||
| taxon:1261581 [Vertebrata]@genus | taxon:2008651 [Polysiphonioideae]@subfamily | genus | Vertebrata |
|
||||
| taxon:7742 [Vertebrata]@clade | taxon:89593 [Craniata]@subphylum | clade | Vertebrata |
|
||||
```
|
||||
|
||||
## A genus called **Vertebrata**
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obitaxonomy -t ncbitaxo_20250211.tgz \
|
||||
-p 2008651 \
|
||||
| csvlook
|
||||
```
|
||||
|
||||
``` csv
|
||||
| taxid | parent | taxonomic_rank | scientific_name |
|
||||
| ------------------------------------------- | ------------------------------------------- | -------------- | ------------------ |
|
||||
| taxon:2008651 [Polysiphonioideae]@subfamily | taxon:2803 [Rhodomelaceae]@family | subfamily | Polysiphonioideae |
|
||||
| taxon:2803 [Rhodomelaceae]@family | taxon:2802 [Ceramiales]@order | family | Rhodomelaceae |
|
||||
| taxon:2802 [Ceramiales]@order | taxon:2045261 [Rhodymeniophycidae]@subclass | order | Ceramiales |
|
||||
| taxon:2045261 [Rhodymeniophycidae]@subclass | taxon:2806 [Florideophyceae]@class | subclass | Rhodymeniophycidae |
|
||||
| taxon:2806 [Florideophyceae]@class | taxon:2763 [Rhodophyta]@phylum | class | Florideophyceae |
|
||||
| taxon:2763 [Rhodophyta]@phylum | taxon:2759 [Eukaryota]@superkingdom | phylum | Rhodophyta |
|
||||
| taxon:2759 [Eukaryota]@superkingdom | taxon:131567 [cellular organisms]@no rank | superkingdom | Eukaryota |
|
||||
| taxon:131567 [cellular organisms]@no rank | taxon:1 [root]@no rank | no rank | cellular organisms |
|
||||
| taxon:1 [root]@no rank | taxon:1 [root]@no rank | no rank | root |
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Reannotation and selection of the genomes
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obiannotate -t ncbitaxo_20250211.tgz \
|
||||
--with-taxon-at-rank=species \
|
||||
mito.all.fasta | \
|
||||
obiannotate -S 'ori_taxid=annotations.taxid' | \
|
||||
obiannotate -S 'taxid=annotations.species_taxid' | \
|
||||
obiuniq -c taxid > mito.one.fasta
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Species representation
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
|
||||
obicsv -k taxid mito.one.fasta \
|
||||
| tail -n +2 \
|
||||
| sort \
|
||||
| uniq -c \
|
||||
| sort -nk1 \
|
||||
| cut -w -f 2 \
|
||||
| uplot count
|
||||
```
|
||||
|
||||
```
|
||||
┌ ┐
|
||||
1 ┤■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■■ 17769.0
|
||||
2 ┤ 90.0
|
||||
3 ┤ 17.0
|
||||
4 ┤ 5.0
|
||||
5 ┤ 4.0
|
||||
6 ┤ 2.0
|
||||
7 ┤ 1.0
|
||||
└ ┘
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Selection of the vertebrata genomes
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
|
||||
obigrep -t ncbitaxo_20250211.tgz \
|
||||
-r 7742 \
|
||||
mito.one.fasta > mito.vert.fasta
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
|
||||
obicount mito.vert.fasta \
|
||||
| csvlook
|
||||
```
|
||||
|
||||
```
|
||||
| entities | n |
|
||||
| -------- | ----------- |
|
||||
| variants | 7,822 |
|
||||
| reads | 7,823 |
|
||||
| symbols | 131,378,756 |
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Prepare data for ecoPrimers 1/3
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
mkdir ncbitaxo_20250211
|
||||
cd ncbitaxo_20250211
|
||||
tar zxvf ../ncbitaxo_20250211.tgz
|
||||
cd ..
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Prepare data for ecoPrimers 2/3
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obiconvert -O mito.vert.fasta > mito.vert.old.fasta
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
head -5 mito.vert.old.fasta
|
||||
```
|
||||
|
||||
``` csv
|
||||
>NC_071784 taxid=taxon:2065826 [Sineleotris saccharae]@species; count=1; ori_taxid=taxon:2065826 [Sineleotris saccharae]@species; scientific_name=mitochondrion Sineleotris saccharae; species_name=Sineleotris saccharae; species_taxid=taxon:2065826 [Sineleotris saccharae]@species; Sineleotris saccharae mitochondrion, complete genome.
|
||||
gctagcgtagcttaaccaaagcataacactgaagatgttaagatgggccctagaaagccc
|
||||
cgcaagcacaaaagcttggtcctggctttactatcagcttaggctaaacttacacatgca
|
||||
agtatccgcatccccgtgagaatgcccttaagctcccaccgctaacaggagtcaaggagc
|
||||
cggtatcaggcacaaccctgagttagcccacgacaccttgctcagccacacccccaaggg
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Prepare data for ecoPrimers 3/3
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
ecoPCRFormat -t ncbitaxo_20250211 \
|
||||
-f \
|
||||
-n vertebrata \
|
||||
mito.vert.old.fasta
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
ls -l vertebrata*
|
||||
```
|
||||
|
||||
```
|
||||
-rw-r--r--@ 1 coissac staff 260899785 Feb 11 11:53 vertabrata.ndx
|
||||
-rw-r--r--@ 1 coissac staff 546 Feb 11 11:53 vertabrata.rdx
|
||||
-rw-r--r--@ 1 coissac staff 121379751 Feb 11 11:53 vertabrata.tdx
|
||||
-rw-r--r--@ 1 coissac staff 40446318 Feb 11 11:54 vertabrata_001.sdx
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Looking for the *Teleostei* `taxid`
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obitaxonomy -t ncbitaxo_20250211.tgz \
|
||||
--fixed \
|
||||
'Teleostei' \
|
||||
| csvlook
|
||||
```
|
||||
|
||||
``` csv
|
||||
| taxid | parent | taxonomic_rank | scientific_name |
|
||||
| ---------------------------------- | ---------------------------------- | -------------- | --------------- |
|
||||
| taxon:32443 [Teleostei]@infraclass | taxon:41665 [Neopterygii]@subclass | infraclass | Teleostei |
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Selecting the best primer pairs
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
ecoPrimers -d vertebrata \
|
||||
-e 3 -3 2 \
|
||||
-l 30 -L 150 \
|
||||
-r 32443 \
|
||||
-c > Teleostei.ecoprimers
|
||||
```
|
||||
|
||||
- Total pair count : 9407
|
||||
- Total good pair count : 407
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
head -35 Teleostei.ecoprimers
|
||||
```
|
||||
|
||||
``` csv
|
||||
#
|
||||
# ecoPrimer version 0.5
|
||||
# Rank level optimisation : species
|
||||
# max error count by oligonucleotide : 3
|
||||
#
|
||||
# Restricted to taxon:
|
||||
# 32443 : Teleostei (infraclass)
|
||||
#
|
||||
# strict primer quorum : 0.70
|
||||
# example quorum : 0.90
|
||||
# counterexample quorum : 0.10
|
||||
#
|
||||
# database : vertebrata
|
||||
# Database is constituted of 3909 examples corresponding to 3876 species
|
||||
# and 0 counterexamples corresponding to 0 species
|
||||
#
|
||||
# amplifiat length between [30,150] bp
|
||||
# DB sequences are considered as circular
|
||||
# Pairs having specificity less than 0.60 will be ignored
|
||||
#
|
||||
0 AGAGTGACGGGCGGTGTG CGTCAGGTCGAGGTGTAG 62.8 42.4 57.5 34.1 12 11 GG 3864 0 0.988 3832 0 0.989 2731 0.713 134 146 138.22
|
||||
1 CGTCAGGTCGAGGTGTAG GAGTGACGGGCGGTGTGT 57.5 34.1 63.1 42.9 11 12 GG 3863 0 0.988 3831 0 0.988 2730 0.713 133 145 137.22
|
||||
2 CGTCAGGTCGAGGTGTAG GGGAGAGTGACGGGCGGT 57.5 34.1 64.5 37.0 11 13 GG 3811 0 0.975 3779 0 0.975 2689 0.712 137 149 141.22
|
||||
3 CGTCAGGTCGAGGTGTAG GGGGAGAGTGACGGGCGG 57.5 34.1 65.5 38.4 11 14 GG 3804 0 0.973 3772 0 0.973 2682 0.711 138 149 142.22
|
||||
4 ACACCGCCCGTCACTCTC ACCTTCCGGTACACTTAC 62.5 36.8 54.0 16.6 12 9 GG 3850 0 0.985 3818 0 0.985 2658 0.696 46 132 66.51
|
||||
5 AACGTCAGGTCGAGGTGT AGAGTGACGGGCGGTGTG 58.8 28.4 62.8 41.7 10 12 GG 3779 0 0.967 3746 0 0.966 2653 0.708 137 148 140.23
|
||||
6 ACACCGCCCGTCACTCTC CACCTTCCGGTACACTTA 62.5 36.8 54.0 16.6 12 9 GG 3846 0 0.984 3814 0 0.984 2654 0.696 47 133 67.51
|
||||
7 AACGTCAGGTCGAGGTGT GAGTGACGGGCGGTGTGT 58.8 28.4 63.1 42.1 10 12 GG 3778 0 0.966 3745 0 0.966 2652 0.708 136 147 139.23
|
||||
8 ACCTTCCGGTACACTTAC CACACCGCCCGTCACTCT 54.0 16.6 62.8 37.3 9 12 GG 3845 0 0.984 3813 0 0.984 2653 0.696 47 133 67.51
|
||||
9 ACACCGCCCGTCACTCTC TCCGGTACACTTACCATG 62.5 36.8 54.1 18.1 12 9 GG 3851 0 0.985 3819 0 0.985 2651 0.694 42 128 62.51
|
||||
10 ACACCGCCCGTCACTCTC CCGGTACACTTACCATGT 62.5 36.8 54.4 18.6 12 9 GG 3851 0 0.985 3819 0 0.985 2651 0.694 41 127 61.51
|
||||
11 ACACCGCCCGTCACTCTC CCAAGTGCACCTTCCGGT 62.5 36.8 60.7 28.9 12 11 GG 3837 0 0.982 3805 0 0.982 2650 0.696 54 140 74.51
|
||||
12 ACACCGCCCGTCACTCTC GCACCTTCCGGTACACTT 62.5 36.8 57.7 22.5 12 10 GG 3842 0 0.983 3810 0 0.983 2650 0.696 48 134 68.51
|
||||
13 ACACCGCCCGTCACTCTC CGGTACACTTACCATGTT 62.5 36.8 52.4 15.7 12 8 GG 3850 0 0.985 3818 0 0.985 2650 0.694 40 126 60.51
|
||||
14 ACACCGCCCGTCACTCTC CACTTACCATGTTACGAC 62.5 36.8 51.1 27.7 12 8 GG 3850 0 0.985 3817 0 0.985 2649 0.694 35 121 55.51
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
- Primer ID : 11
|
||||
|
||||
|
||||
|
||||
| Primer | sequence | tm max | tm min | GC count |
|
||||
|---------|--------------------|--------|--------|----------|
|
||||
| Forward | ACACCGCCCGTCACTCTC | 62.5 | 36.8 | 12 |
|
||||
| Reverse | CCAAGTGCACCTTCCGGT | 60.7 | 28.9 | 11 |
|
||||
|
||||
|
||||
|
||||
- amplifying 3837/3909 sequences\
|
||||
- identify 2650/3876 Species
|
||||
- Size ranging from 54bp to 140bp (mean: 74.75 bp)
|
||||
|
||||
## Testing the new primer pair
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obipcr --forward ACACCGCCCGTCACTCTC \
|
||||
--reverse CCAAGTGCACCTTCCGGT \
|
||||
-e 5 \
|
||||
-l 30 -L 150 \
|
||||
-c \
|
||||
mito.vert.fasta \
|
||||
> Teleostei_11.fasta
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
head Teleostei_11.fasta
|
||||
```
|
||||
|
||||
``` csv
|
||||
>NC_022183_sub[925..998] {"count":1,"definition":"Acrossocheilus hemispinus mitochondrion, complete genome.","direction":"forward","forward_error":1,"forward_match":"acaccgcccgtcaccctc","forward_primer":"ACACCGCCCGTCACTCTC","ori_taxid":"taxon:356810 [Acrossocheilus hemispinus]@species","reverse_error":0,"reverse_match":"ccaagtgcaccttccggt","reverse_primer":"CCAAGTGCACCTTCCGGT","scientific_name":"mitochondrion Acrossocheilus hemispinus","species_name":"Acrossocheilus hemispinus","species_taxid":"taxon:356810 [Acrossocheilus hemispinus]@species","taxid":"taxon:356810 [Acrossocheilus hemispinus]@species"}
|
||||
cccgtcaaaatacaccaaaaatacttaatacaataacactaacaaggggaggcaagtcgt
|
||||
aacatggtaagtgt
|
||||
>NC_018560_sub[916..988] {"count":1,"definition":"Astatotilapia calliptera mitochondrion, complete genome.","direction":"forward","forward_error":0,"forward_match":"acaccgcccgtcactctc","forward_primer":"ACACCGCCCGTCACTCTC","ori_taxid":"taxon:8154 [Astatotilapia calliptera]@species","reverse_error":1,"reverse_match":"ccaagtacaccttccggt","reverse_primer":"CCAAGTGCACCTTCCGGT","scientific_name":"mitochondrion Astatotilapia calliptera (eastern happy)","species_name":"Astatotilapia calliptera","species_taxid":"taxon:8154 [Astatotilapia calliptera]@species","taxid":"taxon:8154 [Astatotilapia calliptera]@species"}
|
||||
cccaagccaacaacatcctataaataatacattttaccggtaaaggggaggcaagtcgta
|
||||
acatggtaagtgt
|
||||
>NC_056117_sub[923..997] {"count":1,"definition":"Pseudocrossocheilus tridentis mitochondrion, complete genome.","direction":"forward","forward_error":0,"forward_match":"acaccgcccgtcactctc","forward_primer":"ACACCGCCCGTCACTCTC","ori_taxid":"taxon:887881 [Pseudocrossocheilus tridentis]@species","reverse_error":0,"reverse_match":"ccaagtgcaccttccggt","reverse_primer":"CCAAGTGCACCTTCCGGT","scientific_name":"mitochondrion Pseudocrossocheilus tridentis","species_name":"Pseudocrossocheilus tridentis","species_taxid":"taxon:887881 [Pseudocrossocheilus tridentis]@species","taxid":"taxon:887881 [Pseudocrossocheilus tridentis]@species"}
|
||||
ccctgtcaaaaagcatcaaatatatataataaattagcaatgacaaggggaggcaagtcg
|
||||
taacacggtaagtgt
|
||||
>NC_045904_sub[919..997] {"count":1,"definition":"Eospalax fontanierii mitochondrion, complete genome.","direction":"forward","forward_error":1,"forward_match":"acaccgcccgtcgctctc","forward_primer":"ACACCGCCCGTCACTCTC","ori_taxid":"taxon:146134 [Eospalax fontanierii]@species","reverse_error":4,"reverse_match":"ccaagcacactttccagt","reverse_primer":"CCAAGTGCACCTTCCGGT","scientific_name":"mitochondrion Eospalax fontanierii","species_name":"Eospalax fontanierii","species_taxid":"taxon:146134 [Eospalax fontanierii]@species","taxid":"taxon:146134 [Eospalax fontanierii]@species"}
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
convert the fasta file to csv
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obicsv --auto -s -i Teleostei_11.fasta > Teleostei_11.csv
|
||||
```
|
||||
|
||||
and display the begining of the table
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
head Teleostei_11.csv | csvlook
|
||||
```
|
||||
|
||||
``` csv
|
||||
| id | count | direction | forward_error | forward_match | forward_primer | ori_taxid | reverse_error | reverse_match | reverse_primer | scientific_name | species_name | species_taxid | taxid | sequence |
|
||||
| ------------------------- | ----- | --------- | ------------- | ------------------ | ------------------ | ---------------------------------------------------- | ------------- | ------------------ | ------------------ | ------------------------------------------------------ | ----------------------------- | ---------------------------------------------------- | ---------------------------------------------------- | ------------------------------------------------------------------------------- |
|
||||
| NC_022183_sub[925..998] | True | forward | True | acaccgcccgtcaccctc | ACACCGCCCGTCACTCTC | taxon:356810 [Acrossocheilus hemispinus]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Acrossocheilus hemispinus | Acrossocheilus hemispinus | taxon:356810 [Acrossocheilus hemispinus]@species | taxon:356810 [Acrossocheilus hemispinus]@species | cccgtcaaaatacaccaaaaatacttaatacaataacactaacaaggggaggcaagtcgtaacatggtaagtgt |
|
||||
| NC_018560_sub[916..988] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:8154 [Astatotilapia calliptera]@species | 1 | ccaagtacaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Astatotilapia calliptera (eastern happy) | Astatotilapia calliptera | taxon:8154 [Astatotilapia calliptera]@species | taxon:8154 [Astatotilapia calliptera]@species | cccaagccaacaacatcctataaataatacattttaccggtaaaggggaggcaagtcgtaacatggtaagtgt |
|
||||
| NC_056117_sub[923..997] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:887881 [Pseudocrossocheilus tridentis]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Pseudocrossocheilus tridentis | Pseudocrossocheilus tridentis | taxon:887881 [Pseudocrossocheilus tridentis]@species | taxon:887881 [Pseudocrossocheilus tridentis]@species | ccctgtcaaaaagcatcaaatatatataataaattagcaatgacaaggggaggcaagtcgtaacacggtaagtgt |
|
||||
| NC_045904_sub[919..997] | True | forward | True | acaccgcccgtcgctctc | ACACCGCCCGTCACTCTC | taxon:146134 [Eospalax fontanierii]@species | 4 | ccaagcacactttccagt | CCAAGTGCACCTTCCGGT | mitochondrion Eospalax fontanierii | Eospalax fontanierii | taxon:146134 [Eospalax fontanierii]@species | taxon:146134 [Eospalax fontanierii]@species | ctcaagtacataaacttggatatattcttaataacccaacaaaaatattagaggagataagtcgtaacaaggtaagcat |
|
||||
| NC_018546_sub[916..987] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:30732 [Oryzias melastigma]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Oryzias melastigma (Indian medaka) | Oryzias melastigma | taxon:30732 [Oryzias melastigma]@species | taxon:30732 [Oryzias melastigma]@species | cccgacccattttaaaaattaaataaaagatttcaggaactaaggggaggcaagtcgtaacatggtaagtgt |
|
||||
| NC_044151_sub[922..993] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:2597641 [Sicyopterus squamosissimus]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Sicyopterus squamosissimus (cling goby) | Sicyopterus squamosissimus | taxon:2597641 [Sicyopterus squamosissimus]@species | taxon:2597641 [Sicyopterus squamosissimus]@species | cccaaaacaaacacacacataaataagaaaaaatgaaaataaaggggaggcaagtcgtaacatggtaagtgt |
|
||||
| NC_044152_sub[922..994] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:2597642 [Sicyopterus stiphodonoides]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Sicyopterus stiphodonoides (cling goby) | Sicyopterus stiphodonoides | taxon:2597642 [Sicyopterus stiphodonoides]@species | taxon:2597642 [Sicyopterus stiphodonoides]@species | cccaaaacaaacacacacataaataagaaaaaantgaaaataaaggggaggcaagtcgtaacatggtaagtgt |
|
||||
| NC_026976_sub[1453..1531] | True | forward | True | acaccgcccgtcactccc | ACACCGCCCGTCACTCTC | taxon:9545 [Macaca nemestrina]@species | 1 | ccaagtgcaccttccagt | CCAAGTGCACCTTCCGGT | mitochondrion Macaca nemestrina (pig-tailed macaque) | Macaca nemestrina | taxon:9545 [Macaca nemestrina]@species | taxon:9545 [Macaca nemestrina]@species | ctcaaatatatttaaggaacatcttaactaaacgccctaatatttatatagaggggataagtcgtaacatggtaagtgt |
|
||||
| NC_031553_sub[921..995] | True | forward | False | acaccgcccgtcactctc | ACACCGCCCGTCACTCTC | taxon:643337 [Puntioplites proctozystron]@species | 0 | ccaagtgcaccttccggt | CCAAGTGCACCTTCCGGT | mitochondrion Puntioplites proctozystron | Puntioplites proctozystron | taxon:643337 [Puntioplites proctozystron]@species | taxon:643337 [Puntioplites proctozystron]@species | ccctgtcaaaacgcactaaaaatatctaatacaaaagcaccgacaaggggaggcaagtcgtaacacggtaagtgt |
|
||||
```
|
||||
|
||||
# We are now switching to R
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Preparing our R session
|
||||
|
||||
First we have to download the two follong libraries
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
library(tidyverse)
|
||||
library(ggpubr)
|
||||
library(ROBITools4)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Loading the data
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
|
||||
fish <- read_csv('Teleostei_11.csv', show_col_types = FALSE)
|
||||
taxo <- read_ncbi_taxdump('ncbitaxo_20250211')
|
||||
assign_default_taxonomy(taxo)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
Looking for Teleostei taxid
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
teleo_taxid <- ecofind('Teleostei')
|
||||
teleo_taxid
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Format taxids
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
fish %>% mutate(
|
||||
taxid = as_taxid(
|
||||
as.integer(
|
||||
str_split_fixed(
|
||||
str_split_fixed(
|
||||
taxid,pattern = " ",
|
||||
n = 2)[,1],
|
||||
":",
|
||||
2)[,2]))
|
||||
) %>%
|
||||
as_tbl_obipcr() %>%
|
||||
mutate(across(taxon(),
|
||||
.names="category",
|
||||
.fn=taxonomy_classifier(Teleostei = 32443))) %>%
|
||||
group_by(category) %>%
|
||||
mutate(weight = taxonomic_weights(taxid,taxo)) %>%
|
||||
ungroup() -> fish
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## The fish tibble
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
head(fish,n = 4)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Identifying which sequences belongs fish
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
table(fish$category)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Testing the conservation of the priming sites
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
pssm_forward <- pssm(fish$forward_match,
|
||||
weights = fish$weight,
|
||||
categories = fish$category)
|
||||
|
||||
pssm_reverse <- pssm(fish$reverse_match,
|
||||
weights = fish$weight,
|
||||
categories = fish$category)
|
||||
```
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
pssm_forward
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Rescaling the matrix as Shanon entropy
|
||||
|
||||
$$
|
||||
H = - \sum_{i \in \{A,C,G,T\}} p_i \times \frac{\log(p_i)}{\log(2)}
|
||||
$$
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
pssm_forward <- pssm_scale_shanon(pssm_forward)
|
||||
pssm_reverse <- pssm_scale_shanon(pssm_reverse)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Display the rescaled matrix
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
pssm_forward
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## The DNA logo of our primer pair
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
flogo <- ggbarcodelogo(pssm_forward) +
|
||||
xlab("Forward primer") + ylab("Bits")
|
||||
rlogo <- ggbarcodelogo(pssm_reverse) +
|
||||
xlab("Reverse primer") + ylab("Bits")
|
||||
|
||||
ggarrange(flogo,rlogo,ncol=2) -> dnaplot
|
||||
|
||||
dnaplot
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## How many mismatches ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
ggbarcodemistmatch(fish$forward_error,
|
||||
fish$reverse_error,
|
||||
otu=fish$species_name,
|
||||
categories=fish$category) + theme_minimal()
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Are we discriminate taxa ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
with(fish %>% filter(category == "Teleostei"),
|
||||
discriminated_at_rank(taxid,
|
||||
c("species","genus","family","order"),
|
||||
sequence))
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## How many sequences will provide information at rank ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
with(fish %>% filter(category == "Teleostei"),
|
||||
discriminant_at_rank(taxid,
|
||||
c("species","genus","family","order"),
|
||||
sequence))
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Is it the same for *Cyprinidae* ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
cyprinidae_taxid <- ecofind('Cyprinidae')
|
||||
cyprinidae_taxid
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Classify according to both categories
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
fish %>%
|
||||
mutate(across(taxon(),
|
||||
.names="category2",
|
||||
.fn=taxonomy_classifier(Teleostei = 32443,
|
||||
Cyprinidae = 7953))) -> fish
|
||||
|
||||
table(fish$category2)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Are we discriminate taxa ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
with(fish %>% filter(category2 == "Cyprinidae"),
|
||||
discriminated_at_rank(taxid,
|
||||
c("species","genus"),
|
||||
sequence))
|
||||
```
|
||||
|
||||
# Go back to unix
|
||||
|
||||
## We run ecoPrimers and ecoPCR on the select primer pair
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
ecoPrimers -d vertebrata \
|
||||
-e 3 -3 2 \
|
||||
-l 30 -L 150 \
|
||||
-r 7953 -c > Cyprinidae.ecoprimers
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obipcr --forward ACGGCGTAAAGGGTGGTT \
|
||||
--reverse TATCTAATCCCAGTTTGT \
|
||||
-e 5 \
|
||||
-l 30 -L 500 \
|
||||
-c \
|
||||
mito.vert.fasta \
|
||||
> Cyprinidae_14.fasta
|
||||
```
|
||||
|
||||
```{bash}
|
||||
#| eval: false
|
||||
#| echo: true
|
||||
obicsv --auto -s -i Cyprinidae_14.fasta > Cyprinidae_14.csv
|
||||
```
|
||||
|
||||
# Go back to R
|
||||
|
||||
```{r}
|
||||
cyprinidae <- read_csv('Cyprinidae_14.csv',
|
||||
show_col_types = FALSE) %>%
|
||||
mutate(
|
||||
taxid = as_taxid(
|
||||
as.integer(
|
||||
str_split_fixed(
|
||||
str_split_fixed(
|
||||
taxid,pattern = " ",
|
||||
n = 2)[,1],
|
||||
":",
|
||||
2)[,2]))
|
||||
) %>%
|
||||
as_tbl_obipcr() %>%
|
||||
mutate(across(taxon(),
|
||||
.names="category",
|
||||
.fn=taxonomy_classifier(Teleostei = 32443,
|
||||
Cyprinidae = 7953))) %>%
|
||||
group_by(category) %>%
|
||||
mutate(weight = taxonomic_weights(taxid,taxo)) %>%
|
||||
ungroup()
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Identifying which sequences belongs fish and *Cyprinidae*
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
table(cyprinidae$category)
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Looking for conservation
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
pssm_forward <- pssm(cyprinidae$forward_match,
|
||||
weights = cyprinidae$weight,
|
||||
categories = cyprinidae$category) %>%
|
||||
pssm_scale_shanon()
|
||||
|
||||
pssm_reverse <- pssm(cyprinidae$reverse_match,
|
||||
weights = cyprinidae$weight,
|
||||
categories = cyprinidae$category) %>%
|
||||
pssm_scale_shanon()
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Plot the new DNA logo
|
||||
|
||||
```{r}
|
||||
flogo <- ggbarcodelogo(pssm_forward) +
|
||||
xlab("Forward primer") + ylab("Bits")
|
||||
rlogo <- ggbarcodelogo(pssm_reverse) +
|
||||
xlab("Reverse primer") + ylab("Bits")
|
||||
|
||||
ggarrange(flogo,rlogo,ncol=2) -> dnaplot
|
||||
|
||||
dnaplot
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## How many mismatches ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
ggbarcodemistmatch(cyprinidae$forward_error,
|
||||
cyprinidae$reverse_error,
|
||||
otu=cyprinidae$species_name,
|
||||
categories=cyprinidae$category) + theme_minimal()
|
||||
```
|
||||
|
||||
------------------------------------------------------------------------
|
||||
|
||||
## Are we discriminate *Cyprinidae* taxa ?
|
||||
|
||||
```{r}
|
||||
#| echo: true
|
||||
with(cyprinidae %>% filter(category == "Cyprinidae"),
|
||||
discriminated_at_rank(taxid,
|
||||
c("species","genus"),
|
||||
sequence))
|
||||
```
|
||||
1227
jupyterhub_volumes/course/biodiversity_metrics_exercises.ipynb
Normal file
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_F.fastq
Normal file
181104
jupyterhub_volumes/course/data/Wolf_diet/wolf_R.fastq
Normal file
@@ -0,0 +1,8 @@
|
||||
@param,matching,strict
|
||||
@param,primer_mismatches,2
|
||||
@param,indels,false
|
||||
experiment,sample,sample_tag,forward_primer,reverse_primer
|
||||
wolf_diet,13a_F730603,aattaac,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
|
||||
wolf_diet,15a_F730814,gaagtag,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
|
||||
wolf_diet,26a_F040644,gaatatc,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
|
||||
wolf_diet,29a_F260619,gcctcct,TTAGATACCCCACTATGC,TAGAACAGGCTCCTCTAG
|
||||
|
1559
jupyterhub_volumes/course/unix_exercises_bash.ipynb
Normal file
3
jupyterhub_volumes/web/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.quarto/
|
||||
**/*.quarto_ipynb
|
||||
/pages/
|
||||
/pages/
|
||||
/obidoc/
|
||||
|
Before Width: | Height: | Size: 217 KiB After Width: | Height: | Size: 350 KiB |
@@ -115,6 +115,7 @@
|
||||
<nav>
|
||||
<ul id="nav-menu"></ul>
|
||||
<ul class="admin-links">
|
||||
<li><a href="/obidoc/" target="_blank">OBITools 4 Doc</a></li>
|
||||
<li><a href="/jupyter/" target="_blank">JupyterHub</a></li>
|
||||
<li><a href="/sftp/" target="_blank">Data Admin</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -1,44 +1,71 @@
|
||||
# ---------- Stage 1 : builder ----------
|
||||
FROM jupyter/base-notebook:latest AS builder
|
||||
# ---------- Stage 1 : builder pour csvlens ----------
|
||||
FROM jupyter/base-notebook:latest AS rust-builder
|
||||
|
||||
USER root
|
||||
|
||||
# Install system dependencies for R, build tools and Go/Rust
|
||||
# Installer seulement les dépendances pour compiler csvlens
|
||||
RUN apt-get update && apt-get install -y \
|
||||
r-base r-base-dev \
|
||||
libcurl4-openssl-dev libssl-dev libxml2-dev \
|
||||
build-essential git curl \
|
||||
&& apt-get clean && rm -rf /var/lib/apt/lists/*
|
||||
curl build-essential zlib1g-dev unzip \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install R kernel + useful packages
|
||||
RUN R -e "install.packages('IRkernel', repos='http://cran.rstudio.com/')" && \
|
||||
R -e "IRkernel::installspec(user = FALSE)" && \
|
||||
R -e "install.packages(c('tidyverse','vegan','ade4'), repos='http://cran.rstudio.com/')"
|
||||
|
||||
# Install bash kernel
|
||||
RUN pip install bash_kernel && python -m bash_kernel.install --sys-prefix
|
||||
# Installer Rust et compiler csvlens
|
||||
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y
|
||||
RUN . $HOME/.cargo/env && cargo install csvlens
|
||||
|
||||
# Install obitools4
|
||||
RUN curl -L https://raw.githubusercontent.com/metabarcoding/obitools4/master/install_obitools.sh | bash
|
||||
RUN TEMP=. curl -L https://raw.githubusercontent.com/metabarcoding/obitools4/master/install_obitools.sh \
|
||||
| bash -s -- --install-dir $HOME/obitools-build \
|
||||
&& cp $HOME/obitools-build/bin/* /usr/local/bin
|
||||
RUN ls -l /usr/local/bin
|
||||
|
||||
# Install csvkit
|
||||
RUN pip install csvkit
|
||||
|
||||
# Install csvlens via Rust
|
||||
RUN curl https://sh.rustup.rs -sSf | bash -s -- -y && \
|
||||
. $HOME/.cargo/env && \
|
||||
cargo install csvlens
|
||||
# ---------- Stage 2 : image finale ----------
|
||||
FROM jupyter/base-notebook:latest
|
||||
|
||||
RUN apt-get update && apt-get install -y ruby ruby-dev build-essential \
|
||||
&& gem install youplot
|
||||
USER root
|
||||
|
||||
# Copy csvlens to /usr/local/bin for final use
|
||||
RUN cp $HOME/.cargo/bin/csvlens /usr/local/bin/
|
||||
# Installer seulement les dépendances d'exécution (sans build-essential)
|
||||
RUN apt-get update && apt-get install -y \
|
||||
r-base \
|
||||
libcurl4-openssl-dev libssl-dev libxml2-dev \
|
||||
curl \
|
||||
git \
|
||||
texlive-xetex texlive-fonts-recommended texlive-plain-generic \
|
||||
ruby ruby-dev \
|
||||
vim nano \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
|
||||
|
||||
# Installer R et packages
|
||||
RUN R -e "install.packages(c('IRkernel','tidyverse','vegan','ade4','BiocManager','remotes','igraph'), \
|
||||
dependencies=TRUE, \
|
||||
repos='http://cran.rstudio.com/')" && \
|
||||
R -e "BiocManager::install('biomformat')" && \
|
||||
R -e "remotes::install_github('metabaRfactory/metabaR')" && \
|
||||
R -e "remotes::install_git('https://forge.metabarcoding.org/obitools/ROBIUtils.git')" && \
|
||||
R -e "remotes::install_git('https://forge.metabarcoding.org/obitools/ROBITaxonomy.git')" && \
|
||||
R -e "remotes::install_git('https://forge.metabarcoding.org/obitools/ROBITools.git')" && \
|
||||
R -e "remotes::install_git('https://forge.metabarcoding.org/obitools/ROBITaxonomy.git')" && \
|
||||
R -e "remotes::install_git('https://forge.metabarcoding.org/MetabarcodingSchool/biodiversity-metrics.git')" && \
|
||||
R -e "IRkernel::installspec(user = FALSE)" && \
|
||||
rm -rf /tmp/Rtmp*
|
||||
|
||||
# Installer les autres outils
|
||||
RUN pip install --no-cache-dir bash_kernel csvkit && \
|
||||
python -m bash_kernel.install --sys-prefix
|
||||
|
||||
RUN gem install youplot
|
||||
|
||||
# Set permissions for Jupyter user
|
||||
RUN mkdir -p /home/${NB_USER}/.local/share/jupyter && \
|
||||
chown -R ${NB_UID}:${NB_GID} /home/${NB_USER}
|
||||
|
||||
|
||||
# Copier uniquement le binaire csvlens du builder
|
||||
COPY --from=rust-builder /home/jovyan/.cargo/bin/csvlens /usr/local/bin/
|
||||
COPY --from=rust-builder /usr/local/bin/* /usr/local/bin/
|
||||
|
||||
COPY start-notebook.sh /usr/local/bin/start-notebook.sh
|
||||
RUN chmod +x /usr/local/bin/start-notebook.sh
|
||||
|
||||
@@ -46,8 +73,6 @@ RUN chmod +x /usr/local/bin/start-notebook.sh
|
||||
USER ${NB_UID}:${NB_GID}
|
||||
WORKDIR /home/${NB_USER}/work
|
||||
|
||||
# Environment variables
|
||||
ENV PATH="/home/${NB_USER}/work/course/bin:${PATH}"
|
||||
ENV R_LIBS_USER="/home/${NB_USER}/work/R_packages"
|
||||
ENV R_LIBS_SITE="/home/${NB_USER}/work/course/R_packages:/usr/local/lib/R/site-library:/usr/lib/R/site-library"
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ RUN pip install dockerspawner
|
||||
|
||||
# Copy configuration
|
||||
COPY jupyterhub_config.py /srv/jupyterhub/jupyterhub_config.py
|
||||
|
||||
COPY jupyterhub_templates/login.html /srv/venv/share/jupyterhub/templates/login.html
|
||||
# Expose port
|
||||
EXPOSE 8000
|
||||
|
||||
|
||||
15191
obijupyterhub/build_student.log
Normal file
@@ -13,8 +13,8 @@ services:
|
||||
- /var/run/docker.sock:/var/run/docker.sock
|
||||
# JupyterHub database persistence
|
||||
- data:/srv/jupyterhub
|
||||
# The Jupyter user volumes
|
||||
- users:/volumes
|
||||
# Mount the parent volumes directory to access users/, shared/, course/
|
||||
- ../jupyterhub_volumes:/volumes
|
||||
# Mount config file directly (for easy modifications)
|
||||
- ./jupyterhub_config.py:/srv/jupyterhub/jupyterhub_config.py:ro
|
||||
networks:
|
||||
@@ -27,6 +27,8 @@ services:
|
||||
JUPYTERHUB_ADMIN_PASSWORD: admin2025
|
||||
# Optional environment variables
|
||||
DOCKER_NOTEBOOK_DIR: /home/jovyan/work
|
||||
# Use PWD to get absolute path relative to docker-compose.yml location
|
||||
HOST_VOLUMES_PATH: ${PWD}/../jupyterhub_volumes
|
||||
|
||||
# ---------- Nginx ----------
|
||||
|
||||
|
||||
@@ -10,7 +10,8 @@ c.JupyterHub.spawner_class = 'dockerspawner.DockerSpawner'
|
||||
c.JupyterHub.log_level = 'DEBUG'
|
||||
c.Spawner.debug = True
|
||||
|
||||
VOLUMES_BASE_PATH = '/volumes'
|
||||
VOLUMES_BASE_PATH = '/volumes/users' # Path as seen from JupyterHub container (for user dirs)
|
||||
HOST_VOLUMES_PATH = os.environ.get('HOST_VOLUMES_PATH', '/volumes') # Real path on host machine (parent dir)
|
||||
|
||||
# Docker image to use for student containers
|
||||
c.DockerSpawner.image = 'jupyterhub-student:latest'
|
||||
@@ -52,32 +53,30 @@ c.DockerSpawner.notebook_dir = notebook_dir
|
||||
async def create_user_dir(spawner):
|
||||
"""Create user directory if it doesn't exist"""
|
||||
user_dir = os.path.join(VOLUMES_BASE_PATH, spawner.user.name)
|
||||
spawner.log.info(f"Ensured user directory exists: {user_dir}")
|
||||
Path(user_dir).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
# Change owner to jovyan user (UID 1000, GID 100 in Jupyter images)
|
||||
os.chown(user_dir, 1000, 100)
|
||||
os.chmod(user_dir, 0o755)
|
||||
|
||||
spawner.log.info(f"Created user directory with correct permissions: {user_dir}")
|
||||
|
||||
c.Spawner.pre_spawn_hook = create_user_dir
|
||||
|
||||
c.DockerSpawner.volumes = {
|
||||
# Personal volume (persistent) - root directory
|
||||
'obijupyterhub_shared-{username}' : '/home/jovyan/work',
|
||||
# Personal volume - bind mount from REAL host path
|
||||
f'{HOST_VOLUMES_PATH}/users/{{username}}': '/home/jovyan/work',
|
||||
# Shared volume between all students - under work/
|
||||
'obijupyterhub_shared': '/home/jovyan/work/shared',
|
||||
f'{HOST_VOLUMES_PATH}/shared': '/home/jovyan/work/shared',
|
||||
# Shared read-only volume for course files - under work/
|
||||
'obijupyterhub_course': {
|
||||
f'{HOST_VOLUMES_PATH}/course': {
|
||||
'bind': '/home/jovyan/work/course',
|
||||
'mode': 'ro' # read-only
|
||||
}
|
||||
}
|
||||
|
||||
c.DockerSpawner.volume_driver = 'local'
|
||||
c.DockerSpawner.volume_driver_opts = {
|
||||
'type': 'none',
|
||||
'device': '/volumes',
|
||||
'o': 'bind'
|
||||
}
|
||||
# Memory and CPU configuration (adjust according to your needs)
|
||||
c.DockerSpawner.mem_limit = '2G'
|
||||
c.DockerSpawner.mem_limit = '6G'
|
||||
c.DockerSpawner.cpu_limit = 1.0
|
||||
|
||||
# User configuration - Simple password authentication for lab
|
||||
|
||||
229
obijupyterhub/jupyterhub_templates/login.html
Normal file
@@ -0,0 +1,229 @@
|
||||
{% extends "page.html" %} {% if announcement_login is string %} {% set
|
||||
announcement = announcement_login %} {% endif %} {% block head %} {{ super() }}
|
||||
<style>
|
||||
body {
|
||||
background: radial-gradient(
|
||||
circle at top,
|
||||
#f9f8ff 0%,
|
||||
#f1f5ff 45%,
|
||||
#e7eefb 100%
|
||||
);
|
||||
min-height: 100vh;
|
||||
font-family: "Inter", "Helvetica Neue", Arial, sans-serif;
|
||||
}
|
||||
#login-main {
|
||||
max-width: 950px;
|
||||
margin: 4rem auto;
|
||||
padding: 0;
|
||||
}
|
||||
.metabar-card {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
box-shadow: 0 20px 60px rgba(30, 50, 120, 0.15);
|
||||
border-radius: 28px;
|
||||
overflow: hidden;
|
||||
background: white;
|
||||
}
|
||||
.auth-form-body img#metabar-img {
|
||||
width: 200px; /* ajuste selon le rendu souhaité */
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto 1rem;
|
||||
}
|
||||
.login-panel {
|
||||
flex: 1 1 360px;
|
||||
padding: 2.5rem;
|
||||
}
|
||||
.login-panel h2 {
|
||||
font-weight: 600;
|
||||
margin-bottom: 0.25rem;
|
||||
}
|
||||
.login-panel p.subtitle {
|
||||
color: #667080;
|
||||
margin-bottom: 1.75rem;
|
||||
}
|
||||
.auth-form-body label {
|
||||
font-size: 0.85rem;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
font-weight: 600;
|
||||
color: #6b7280;
|
||||
}
|
||||
.auth-form-body input.form-control {
|
||||
border-radius: 14px;
|
||||
padding: 0.85rem 1rem;
|
||||
border: 1px solid #d7def0;
|
||||
transition: border-color 0.2s ease, box-shadow 0.2s ease;
|
||||
}
|
||||
.auth-form-body input.form-control:focus {
|
||||
border-color: #6b8afd;
|
||||
box-shadow: 0 0 0 3px rgba(107, 138, 253, 0.2);
|
||||
outline: none;
|
||||
}
|
||||
.btn.btn-jupyter {
|
||||
background: linear-gradient(135deg, #6b8afd, #3f6dd9);
|
||||
border: none;
|
||||
border-radius: 14px;
|
||||
padding: 0.85rem 0;
|
||||
font-weight: 600;
|
||||
text-transform: uppercase;
|
||||
letter-spacing: 0.08em;
|
||||
}
|
||||
.metabar-footnote {
|
||||
font-size: 0.82rem;
|
||||
color: #94a3b8;
|
||||
margin-top: 1.5rem;
|
||||
}
|
||||
@media (max-width: 900px) {
|
||||
#login-main {
|
||||
margin: 2rem 1rem;
|
||||
}
|
||||
.metabar-card {
|
||||
flex-direction: column;
|
||||
}
|
||||
.metabar-hero img {
|
||||
position: relative;
|
||||
opacity: 1;
|
||||
}
|
||||
.metabar-hero__overlay {
|
||||
background: rgba(4, 20, 43, 0.85);
|
||||
border-radius: inherit;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
{% endblock head %} {% block login_widget %}{% endblock login_widget %} {% block
|
||||
main %} {% block login %}
|
||||
<div id="login-main" class="container">
|
||||
<div class="metabar-card">
|
||||
<section class="login-panel">
|
||||
<h2></h2>
|
||||
<p class="subtitle"></p>
|
||||
{% block login_container %} {% if custom_html %} {{ custom_html | safe }}
|
||||
{% elif login_service %}
|
||||
<div class="service-login">
|
||||
<a
|
||||
role="button"
|
||||
class="btn btn-jupyter btn-lg w-100"
|
||||
href="{{ authenticator_login_url | safe }}"
|
||||
>Sign in with {{ login_service }}</a
|
||||
>
|
||||
</div>
|
||||
{% else %}
|
||||
<form
|
||||
action="{{ authenticator_login_url | safe }}"
|
||||
method="post"
|
||||
role="form"
|
||||
>
|
||||
<div class="auth-form-body">
|
||||
{% if login_error %}
|
||||
<p class="login_error">{{ login_error }}</p>
|
||||
{% endif %}
|
||||
<img
|
||||
id="metabar-img"
|
||||
src="/img/welcome_metabar.webp"
|
||||
alt="Metabarcoding welcome illustration"
|
||||
style="
|
||||
width: 308px;
|
||||
height: auto;
|
||||
display: block;
|
||||
margin: 0 auto 1rem;
|
||||
"
|
||||
/>
|
||||
<input type="hidden" name="_xsrf" value="{{ xsrf }}" />
|
||||
{% block username_input %}
|
||||
<label for="username_input">Username</label>
|
||||
<input
|
||||
id="username_input"
|
||||
{%
|
||||
block
|
||||
username_input_attrs
|
||||
%}
|
||||
type="text"
|
||||
autocapitalize="off"
|
||||
autocorrect="off"
|
||||
autocomplete="username"
|
||||
class="form-control"
|
||||
name="username"
|
||||
value="{{ username }}"
|
||||
autofocus="autofocus"
|
||||
{%
|
||||
endblock
|
||||
username_input_attrs
|
||||
%}
|
||||
/>
|
||||
{% endblock username_input %} {% block password_input %}
|
||||
<label for="password_input">Password</label>
|
||||
<input
|
||||
id="password_input"
|
||||
{%
|
||||
block
|
||||
password_input_attrs
|
||||
%}
|
||||
type="password"
|
||||
class="form-control"
|
||||
autocomplete="current-password"
|
||||
name="password"
|
||||
{%
|
||||
endblock
|
||||
password_input_attrs
|
||||
%}
|
||||
/>
|
||||
{% endblock password_input %} {% if authenticator.request_otp %} {%
|
||||
block otp_input %}
|
||||
<label for="otp_input">{{ authenticator.otp_prompt }}</label>
|
||||
<input
|
||||
id="otp_input"
|
||||
{%
|
||||
block
|
||||
otp_input_attrs
|
||||
%}
|
||||
class="form-control"
|
||||
autocomplete="one-time-password"
|
||||
name="otp"
|
||||
{%
|
||||
endblock
|
||||
otp_input_attrs
|
||||
%}
|
||||
/>
|
||||
{% endblock otp_input %} {% endif %}
|
||||
<div class="feedback-container mt-4">
|
||||
<input
|
||||
id="login_submit"
|
||||
type="submit"
|
||||
class="btn btn-jupyter form-control"
|
||||
value="Sign in"
|
||||
tabindex="3"
|
||||
/>
|
||||
<div class="feedback-widget hidden">
|
||||
<i class="fa fa-spinner"></i>
|
||||
</div>
|
||||
</div>
|
||||
{% block login_terms %} {% if login_term_url %}
|
||||
<div id="login_terms" class="login_terms mt-3">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="login_terms_checkbox"
|
||||
name="login_terms_checkbox"
|
||||
required
|
||||
/>
|
||||
{% block login_terms_text %} By logging in you accept the
|
||||
<a href="{{ login_term_url }}">terms and conditions</a>. {% endblock
|
||||
login_terms_text %}
|
||||
</div>
|
||||
{% endif %} {% endblock login_terms %}
|
||||
</div>
|
||||
</form>
|
||||
{% endif %} {% endblock login_container %}
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
{% endblock login %} {% endblock main %} {% block script %} {{ super() }}
|
||||
<script>
|
||||
$("form").submit((e) => {
|
||||
const form = $(e.target);
|
||||
form.find(".feedback-container>input").attr("disabled", true);
|
||||
form.find(".feedback-container>*").toggleClass("hidden");
|
||||
form.find(".feedback-widget>*").toggleClass("fa-pulse");
|
||||
});
|
||||
</script>
|
||||
{% endblock script %}
|
||||
93675
ref_db_raw.fasta
Normal file
@@ -1,36 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
# JupyterHub startup script for labs
|
||||
# Usage: ./start-jupyterhub.sh
|
||||
# Usage: ./start-jupyterhub.sh [--no-build|--offline] [--force-rebuild] [--stop-server] [--update-lectures] [--build-obidoc]
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||
DOCKER_DIR="${SCRIPT_DIR}/obijupyterhub/"
|
||||
|
||||
set -e # Stop on error
|
||||
|
||||
echo "🚀 Starting JupyterHub for Lab"
|
||||
echo "=============================="
|
||||
echo ""
|
||||
|
||||
# Compile the web site
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building the volume directories...${NC}"
|
||||
pushd "${SCRIPT_DIR}/jupyterhub_volumes"
|
||||
mkdir -p caddy
|
||||
mkdir -p course/bin
|
||||
mkdir -p course/R_packages
|
||||
mkdir -p jupyterhub
|
||||
mkdir -p shared
|
||||
mkdir -p users
|
||||
popd
|
||||
|
||||
# Colors for display
|
||||
GREEN='\033[0;32m'
|
||||
BLUE='\033[0;34m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
pushd "${DOCKER_DIR}"
|
||||
NO_BUILD=false
|
||||
FORCE_REBUILD=false
|
||||
STOP_SERVER=false
|
||||
UPDATE_LECTURES=false
|
||||
BUILD_OBIDOC=false
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ./start-jupyterhub.sh [options]
|
||||
|
||||
Options:
|
||||
--no-build | --offline Skip Docker image builds (use existing images)
|
||||
--force-rebuild Rebuild images without cache
|
||||
--stop-server Stop the stack and remove student containers, then exit
|
||||
--update-lectures Rebuild the course website only (no Docker stop/start)
|
||||
--build-obidoc Force rebuild of obidoc documentation
|
||||
-h, --help Show this help
|
||||
EOF
|
||||
}
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--no-build|--offline) NO_BUILD=true ;;
|
||||
--force-rebuild) FORCE_REBUILD=true ;;
|
||||
--stop-server) STOP_SERVER=true ;;
|
||||
--update-lectures) UPDATE_LECTURES=true ;;
|
||||
--build-obidoc) BUILD_OBIDOC=true ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
*) echo "Unknown option: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if $STOP_SERVER && $UPDATE_LECTURES; then
|
||||
echo "❌ --stop-server and --update-lectures cannot be used together" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "🚀 Starting JupyterHub for Lab"
|
||||
echo "=============================="
|
||||
echo ""
|
||||
|
||||
echo -e "${BLUE}🔨 Building the volume directories...${NC}"
|
||||
pushd "${SCRIPT_DIR}/jupyterhub_volumes" >/dev/null
|
||||
mkdir -p caddy
|
||||
mkdir -p course/bin
|
||||
mkdir -p course/R_packages
|
||||
mkdir -p jupyterhub
|
||||
mkdir -p shared
|
||||
mkdir -p users
|
||||
mkdir -p web/obidoc
|
||||
popd >/dev/null
|
||||
|
||||
pushd "${DOCKER_DIR}" >/dev/null
|
||||
|
||||
# Check we're in the right directory
|
||||
if [ ! -f "Dockerfile" ] || [ ! -f "docker-compose.yml" ]; then
|
||||
@@ -38,74 +75,152 @@ if [ ! -f "Dockerfile" ] || [ ! -f "docker-compose.yml" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Stop existing containers
|
||||
echo -e "${BLUE}📦 Stopping existing containers...${NC}"
|
||||
docker-compose down 2>/dev/null || true
|
||||
stop_stack() {
|
||||
echo -e "${BLUE}📦 Stopping existing containers...${NC}"
|
||||
docker-compose down 2>/dev/null || true
|
||||
|
||||
# Remove old student containers
|
||||
echo -e "${BLUE}🧹 Cleaning up student containers...${NC}"
|
||||
docker ps -aq --filter name=jupyter- | xargs -r docker rm -f 2>/dev/null || true
|
||||
echo -e "${BLUE}🧹 Cleaning up student containers...${NC}"
|
||||
docker ps -aq --filter name=jupyter- | xargs -r docker rm -f 2>/dev/null || true
|
||||
}
|
||||
|
||||
# Build student image
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building student image...${NC}"
|
||||
docker build -t jupyterhub-student:latest -f Dockerfile .
|
||||
build_images() {
|
||||
if $NO_BUILD; then
|
||||
echo -e "${YELLOW}⏭️ Skipping image builds (offline/no-build mode).${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Build hub image
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building JupyterHub image...${NC}"
|
||||
docker build -t jupyterhub-hub:latest -f Dockerfile.hub .
|
||||
local build_flag=()
|
||||
if $FORCE_REBUILD; then
|
||||
build_flag+=(--no-cache)
|
||||
fi
|
||||
|
||||
# Compile the web site
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building web site...${NC}"
|
||||
pushd ../web_src
|
||||
quarto render
|
||||
python3 ../tools/generate_pages_json.py
|
||||
popd
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building student image...${NC}"
|
||||
docker build "${build_flag[@]}" -t jupyterhub-student:latest -f Dockerfile .
|
||||
|
||||
# Start the stack
|
||||
echo ""
|
||||
echo -e "${BLUE}🚀 Starting JupyterHub...${NC}"
|
||||
docker-compose up -d --remove-orphans
|
||||
echo ""
|
||||
echo -e "${BLUE}🔨 Building JupyterHub image...${NC}"
|
||||
docker build "${build_flag[@]}" -t jupyterhub-hub:latest -f Dockerfile.hub .
|
||||
}
|
||||
|
||||
# Wait for service to be ready
|
||||
echo ""
|
||||
echo -e "${YELLOW}⏳ Waiting for JupyterHub to start...${NC}"
|
||||
sleep 3
|
||||
build_obidoc() {
|
||||
local dest="${SCRIPT_DIR}/jupyterhub_volumes/web/obidoc"
|
||||
|
||||
popd
|
||||
if $NO_BUILD; then
|
||||
echo -e "${YELLOW}⏭️ Skipping obidoc build in offline/no-build mode.${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
local needs_build=false
|
||||
if $BUILD_OBIDOC; then
|
||||
needs_build=true
|
||||
elif [ -z "$(ls -A "$dest" 2>/dev/null)" ]; then
|
||||
needs_build=true
|
||||
fi
|
||||
|
||||
if ! $needs_build; then
|
||||
echo -e "${BLUE}ℹ️ obidoc already present; skipping rebuild (use --build-obidoc to force).${NC}"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check that container is running
|
||||
if docker ps | grep -q jupyterhub; then
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ JupyterHub is running!${NC}"
|
||||
echo -e "${BLUE}🔨 Building obidoc documentation...${NC}"
|
||||
BUILD_DIR=$(mktemp -d -p .)
|
||||
pushd "$BUILD_DIR" >/dev/null
|
||||
git clone --recurse-submodules \
|
||||
--remote-submodules \
|
||||
-j 8 \
|
||||
https://github.com/metabarcoding/obitools4-doc.git
|
||||
pushd obitools4-doc >/dev/null
|
||||
hugo -D build --baseURL "/obidoc/"
|
||||
mkdir -p "$dest"
|
||||
rm -rf "${dest:?}/"*
|
||||
mv public/* "$dest"
|
||||
popd >/dev/null
|
||||
popd >/dev/null
|
||||
rm -rf
|
||||
}
|
||||
|
||||
build_website() {
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo -e "${GREEN}🌐 JupyterHub available at: http://localhost:8888${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo -e "${BLUE}🔨 Building web site...${NC}"
|
||||
pushd ../web_src >/dev/null
|
||||
quarto render
|
||||
find . -name '*.pdf' -print \
|
||||
| while read pdfname ; do
|
||||
dest="../jupyterhub_volumes/web/pages/${pdfname}"
|
||||
dirdest=$(dirname "$dest")
|
||||
mkdir -p "$dirdest"
|
||||
echo "cp '${pdfname}' '${dest}'"
|
||||
done \
|
||||
| bash
|
||||
python3 ../tools/generate_pdf_galleries.py
|
||||
python3 ../tools/generate_pages_json.py
|
||||
popd >/dev/null
|
||||
}
|
||||
|
||||
start_stack() {
|
||||
echo ""
|
||||
echo "📝 Password: metabar2025"
|
||||
echo "👥 Students can connect with any username"
|
||||
echo -e "${BLUE}🚀 Starting JupyterHub...${NC}"
|
||||
docker-compose up -d --remove-orphans
|
||||
|
||||
echo ""
|
||||
echo "🔑 Admin account:"
|
||||
echo " Username: admin"
|
||||
echo " Password: admin2025"
|
||||
echo ""
|
||||
echo "📂 Each student will have access to:"
|
||||
echo " - work/ : personal workspace (everything saved)"
|
||||
echo " - work/R_packages/ : personal R packages (writable)"
|
||||
echo " - work/shared/ : shared workspace"
|
||||
echo " - work/course/ : course files (read-only)"
|
||||
echo " - work/course/R_packages/ : shared R packages by prof (read-only)"
|
||||
echo " - work/course/bin/ : shared executables (in PATH)"
|
||||
echo ""
|
||||
echo "🔍 To view logs: docker-compose logs -f jupyterhub"
|
||||
echo "🛑 To stop: docker-compose down"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}⚠️ JupyterHub container doesn't seem to be starting${NC}"
|
||||
echo "Check logs with: docker-compose logs jupyterhub"
|
||||
exit 1
|
||||
echo -e "${YELLOW}⏳ Waiting for JupyterHub to start...${NC}"
|
||||
sleep 3
|
||||
}
|
||||
|
||||
print_success() {
|
||||
if docker ps | grep -q jupyterhub; then
|
||||
echo ""
|
||||
echo -e "${GREEN}✅ JupyterHub is running!${NC}"
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo -e "${GREEN}🌐 JupyterHub available at: http://localhost:8888${NC}"
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
echo ""
|
||||
echo "📝 Password: metabar2025"
|
||||
echo "👥 Students can connect with any username"
|
||||
echo ""
|
||||
echo "🔑 Admin account:"
|
||||
echo " Username: admin"
|
||||
echo " Password: admin2025"
|
||||
echo ""
|
||||
echo "📂 Each student will have access to:"
|
||||
echo " - work/ : personal workspace (everything saved)"
|
||||
echo " - work/R_packages/ : personal R packages (writable)"
|
||||
echo " - work/shared/ : shared workspace"
|
||||
echo " - work/course/ : course files (read-only)"
|
||||
echo " - work/course/R_packages/ : shared R packages by prof (read-only)"
|
||||
echo " - work/course/bin/ : shared executables (in PATH)"
|
||||
echo ""
|
||||
echo "🔍 To view logs: docker-compose logs -f jupyterhub"
|
||||
echo "🛑 To stop: docker-compose down"
|
||||
echo ""
|
||||
else
|
||||
echo ""
|
||||
echo -e "${YELLOW}⚠️ JupyterHub container doesn't seem to be starting${NC}"
|
||||
echo "Check logs with: docker-compose logs jupyterhub"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
if $STOP_SERVER; then
|
||||
stop_stack
|
||||
popd >/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if $UPDATE_LECTURES; then
|
||||
build_website
|
||||
popd >/dev/null
|
||||
exit 0
|
||||
fi
|
||||
|
||||
stop_stack
|
||||
build_images
|
||||
build_website
|
||||
build_obidoc
|
||||
start_stack
|
||||
|
||||
popd >/dev/null
|
||||
print_success
|
||||
|
||||
170
tools/generate_pdf_galleries.py
Normal file
@@ -0,0 +1,170 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Generate lightweight HTML galleries for PDF files within PAGES_DIR."""
|
||||
from __future__ import annotations
|
||||
|
||||
import html
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Iterable, List, Tuple
|
||||
from urllib.parse import quote
|
||||
|
||||
SCRIPT_DIR = Path(__file__).resolve().parent
|
||||
PAGES_DIR = (SCRIPT_DIR / ".." / "jupyterhub_volumes" / "web" / "pages").resolve()
|
||||
|
||||
GALLERY_TEMPLATE = """<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>{title}</title>
|
||||
<style>
|
||||
:root {{
|
||||
font-family: system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
|
||||
color: #222;
|
||||
background: #f8f8f8;
|
||||
}}
|
||||
body {{
|
||||
margin: 2rem;
|
||||
}}
|
||||
h1 {{
|
||||
font-size: 1.4rem;
|
||||
margin-bottom: 1rem;
|
||||
}}
|
||||
.gallery {{
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
|
||||
gap: 1rem;
|
||||
}}
|
||||
.pdf-card {{
|
||||
background: #fff;
|
||||
border-radius: 8px;
|
||||
padding: 0.75rem;
|
||||
text-decoration: none;
|
||||
color: inherit;
|
||||
box-shadow: 0 1px 4px rgb(15 15 15 / 12%);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
}}
|
||||
.pdf-card:hover {{
|
||||
box-shadow: 0 4px 12px rgb(15 15 15 / 18%);
|
||||
}}
|
||||
.pdf-card object {{
|
||||
width: 150px;
|
||||
height: 200px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background: #fafafa;
|
||||
pointer-events: none;
|
||||
}}
|
||||
.pdf-fallback {{
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
font-size: 0.8rem;
|
||||
color: #777;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding: 0.5rem;
|
||||
text-align: center;
|
||||
}}
|
||||
.pdf-label {{
|
||||
font-weight: 500;
|
||||
text-align: center;
|
||||
}}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{title}</h1>
|
||||
<div class="gallery">
|
||||
{cards}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
"""
|
||||
|
||||
ITEM_TEMPLATE = """ <a class="pdf-card" href="{link_href}" target="_blank" rel="noopener">
|
||||
<object data="{object_src}" type="application/pdf" aria-label="{label}">
|
||||
<div class="pdf-fallback">
|
||||
<span>{label}</span>
|
||||
<small>Prévisualisation indisponible</small>
|
||||
</div>
|
||||
</object>
|
||||
<span class="pdf-label">{label}</span>
|
||||
</a>"""
|
||||
|
||||
|
||||
def clean_label(entry_name: str) -> str:
|
||||
"""Remove numeric prefixes and make a readable label."""
|
||||
base = Path(entry_name).stem
|
||||
base = re.sub(r"^\d+[_\-\s]*", "", base)
|
||||
base = base.replace("_", " ").replace("-", " ")
|
||||
base = re.sub(r"\s+", " ", base).strip()
|
||||
return base.capitalize() if base else Path(entry_name).stem
|
||||
|
||||
|
||||
def should_skip_dir(dirname: str) -> bool:
|
||||
"""Return True if we should ignore the directory while walking."""
|
||||
return dirname.startswith(".") or dirname.endswith("libs") or dirname == "__pycache__"
|
||||
|
||||
|
||||
def iter_pdf_directories(root: Path) -> Iterable[Tuple[Path, List[str]]]:
|
||||
"""Yield directories in root containing at least one PDF file."""
|
||||
for current_dir, dirnames, filenames in os.walk(root):
|
||||
dirnames[:] = [name for name in dirnames if not should_skip_dir(name)]
|
||||
pdfs = sorted(name for name in filenames if name.lower().endswith(".pdf"))
|
||||
if pdfs:
|
||||
yield Path(current_dir), pdfs
|
||||
|
||||
|
||||
def directory_label(directory: Path) -> str:
|
||||
"""Return a human-readable label for the given directory."""
|
||||
try:
|
||||
relative = directory.relative_to(PAGES_DIR)
|
||||
except ValueError:
|
||||
relative = directory
|
||||
if not relative.parts:
|
||||
return "Documents"
|
||||
return " / ".join(clean_label(part) for part in relative.parts)
|
||||
|
||||
|
||||
def build_gallery_html(directory: Path, pdf_files: List[str]) -> str:
|
||||
"""Create the HTML content for all PDFs in the directory."""
|
||||
cards = []
|
||||
for filename in pdf_files:
|
||||
label = html.escape(clean_label(filename))
|
||||
href = quote(filename)
|
||||
object_src = f"{href}#page=1&view=Fit"
|
||||
cards.append(
|
||||
ITEM_TEMPLATE.format(
|
||||
link_href=html.escape(href, quote=True),
|
||||
object_src=html.escape(object_src, quote=True),
|
||||
label=label,
|
||||
)
|
||||
)
|
||||
title = html.escape(directory_label(directory))
|
||||
return GALLERY_TEMPLATE.format(title=title, cards="\n".join(cards))
|
||||
|
||||
|
||||
def main() -> None:
|
||||
if not PAGES_DIR.exists():
|
||||
raise SystemExit(f"❌ PAGES_DIR inexistant: {PAGES_DIR}")
|
||||
|
||||
generated = 0
|
||||
for directory, pdf_files in iter_pdf_directories(PAGES_DIR):
|
||||
html_content = build_gallery_html(directory, pdf_files)
|
||||
output_path = directory / "documents.html"
|
||||
output_path.write_text(html_content, encoding="utf-8")
|
||||
rel_out = output_path.relative_to(PAGES_DIR)
|
||||
print(f"✅ {rel_out} ({len(pdf_files)} PDF)")
|
||||
generated += 1
|
||||
|
||||
if not generated:
|
||||
print("ℹ️ Aucun PDF trouvé, aucun document.html généré.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
1
web_src/.gitignore
vendored
@@ -1,3 +1,4 @@
|
||||
/.quarto/
|
||||
**/*.quarto_ipynb
|
||||
/_output/
|
||||
sandbox/
|
||||
@@ -2,8 +2,11 @@
|
||||
title: "Regular Expressions"
|
||||
format:
|
||||
revealjs:
|
||||
theme: beige # thème des slides
|
||||
transition: fade # effet de transition entre les slides
|
||||
css: ../../slides.css
|
||||
transition: slide
|
||||
scrollable: true
|
||||
theme: beige
|
||||
html-math-method: mathjax
|
||||
---
|
||||
|
||||
|
||||
BIN
web_src/05_Lectures/00_Computers/unix/images/OBITools-web.png
Normal file
|
After Width: | Height: | Size: 155 KiB |
420
web_src/05_Lectures/00_Computers/unix/images/automata.svg
Normal file
@@ -0,0 +1,420 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="409.5723"
|
||||
height="199.73067"
|
||||
id="svg4800"
|
||||
version="1.1"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="automata.svg">
|
||||
<defs
|
||||
id="defs4802">
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
id="path5507"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend-3"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5507-4"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend-3-1"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5507-4-6"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend-3-19"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5507-4-9"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend-3-5"
|
||||
style="overflow:visible">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path5507-4-1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 z"
|
||||
style="fill-rule:evenodd;stroke:#000000;stroke-width:1pt"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="123.22225"
|
||||
inkscape:cy="-3.6611703"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
inkscape:window-width="1617"
|
||||
inkscape:window-height="1026"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
fit-margin-top="0"
|
||||
fit-margin-left="0"
|
||||
fit-margin-right="0"
|
||||
fit-margin-bottom="0" />
|
||||
<metadata
|
||||
id="metadata4805">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-48.115765,21.455475)">
|
||||
<g
|
||||
id="g8279"
|
||||
transform="translate(-40.911178,-11.616754)">
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="node"
|
||||
id="node3">
|
||||
<title
|
||||
id="title8115">0</title>
|
||||
<ellipse
|
||||
id="ellipse8117"
|
||||
ry="18"
|
||||
rx="18"
|
||||
cy="-21"
|
||||
cx="110"
|
||||
sodipodi:cx="110"
|
||||
sodipodi:cy="-21"
|
||||
sodipodi:rx="18"
|
||||
sodipodi:ry="18"
|
||||
style="fill:none;stroke:#000000"
|
||||
d="m 128,-21 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z" />
|
||||
<text
|
||||
id="text8119"
|
||||
font-size="14.00"
|
||||
y="-17.299999"
|
||||
x="110"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">0</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="edge"
|
||||
id="edge1">
|
||||
<title
|
||||
id="title8122">I->0</title>
|
||||
<path
|
||||
id="path8124"
|
||||
d="m 54.0748,-21 c 8.8116,0 18.6712,0 27.5786,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000" />
|
||||
<polygon
|
||||
id="polygon8126"
|
||||
points="81.9117,-24.5001 81.9117,-24.5001 91.9117,-21 81.9117,-17.5001 "
|
||||
style="fill:#000000;stroke:#000000" />
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="node"
|
||||
id="node2">
|
||||
<title
|
||||
id="title8129">3</title>
|
||||
<ellipse
|
||||
id="ellipse8131"
|
||||
ry="18"
|
||||
rx="18"
|
||||
cy="-21"
|
||||
cx="350"
|
||||
sodipodi:cx="350"
|
||||
sodipodi:cy="-21"
|
||||
sodipodi:rx="18"
|
||||
sodipodi:ry="18"
|
||||
style="fill:none;stroke:#000000"
|
||||
d="m 368,-21 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z" />
|
||||
<ellipse
|
||||
id="ellipse8133"
|
||||
ry="22"
|
||||
rx="22"
|
||||
cy="-21"
|
||||
cx="350"
|
||||
sodipodi:cx="350"
|
||||
sodipodi:cy="-21"
|
||||
sodipodi:rx="22"
|
||||
sodipodi:ry="22"
|
||||
style="fill:none;stroke:#000000"
|
||||
d="m 372,-21 c 0,12.1502645 -9.84974,22 -22,22 -12.15026,0 -22,-9.8497355 -22,-22 0,-12.150264 9.84974,-22 22,-22 12.15026,0 22,9.849736 22,22 z" />
|
||||
<text
|
||||
id="text8135"
|
||||
font-size="14.00"
|
||||
y="-17.299999"
|
||||
x="350"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">3</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="node"
|
||||
id="node4">
|
||||
<title
|
||||
id="title8138">1</title>
|
||||
<ellipse
|
||||
id="ellipse8140"
|
||||
ry="18"
|
||||
rx="18"
|
||||
cy="-21"
|
||||
cx="186"
|
||||
sodipodi:cx="186"
|
||||
sodipodi:cy="-21"
|
||||
sodipodi:rx="18"
|
||||
sodipodi:ry="18"
|
||||
style="fill:none;stroke:#000000"
|
||||
d="m 204,-21 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z" />
|
||||
<text
|
||||
id="text8142"
|
||||
font-size="14.00"
|
||||
y="-17.299999"
|
||||
x="186"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">1</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="edge"
|
||||
id="edge2">
|
||||
<title
|
||||
id="title8145">0->1</title>
|
||||
<path
|
||||
id="path8147"
|
||||
d="m 128.163,-21 c 8.779,0 19.674,0 29.57,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000" />
|
||||
<polygon
|
||||
id="polygon8149"
|
||||
points="157.93,-24.5001 157.93,-24.5001 167.93,-21 157.93,-17.5001 "
|
||||
style="fill:#000000;stroke:#000000" />
|
||||
<text
|
||||
id="text8151"
|
||||
font-size="14.00"
|
||||
y="-24.799999"
|
||||
x="148"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">t</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="node"
|
||||
id="node5">
|
||||
<title
|
||||
id="title8154">2</title>
|
||||
<ellipse
|
||||
id="ellipse8156"
|
||||
ry="18"
|
||||
rx="18"
|
||||
cy="-21"
|
||||
cx="266"
|
||||
sodipodi:cx="266"
|
||||
sodipodi:cy="-21"
|
||||
sodipodi:rx="18"
|
||||
sodipodi:ry="18"
|
||||
style="fill:none;stroke:#000000"
|
||||
d="m 284,-21 c 0,9.941125 -8.05887,18 -18,18 -9.94113,0 -18,-8.058875 -18,-18 0,-9.941125 8.05887,-18 18,-18 9.94113,0 18,8.058875 18,18 z" />
|
||||
<text
|
||||
id="text8158"
|
||||
font-size="14.00"
|
||||
y="-17.299999"
|
||||
x="266"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">2</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="edge"
|
||||
id="edge3">
|
||||
<title
|
||||
id="title8161">1->2</title>
|
||||
<path
|
||||
id="path8163"
|
||||
d="m 204.311,-21 c 9.795,0 22.267,0 33.354,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000" />
|
||||
<polygon
|
||||
id="polygon8165"
|
||||
points="237.738,-24.5001 237.738,-24.5001 247.738,-21 237.738,-17.5001 "
|
||||
style="fill:#000000;stroke:#000000" />
|
||||
<text
|
||||
id="text8167"
|
||||
font-size="14.00"
|
||||
y="-24.799999"
|
||||
x="226"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">o</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="edge"
|
||||
id="edge5">
|
||||
<title
|
||||
id="title8170">2->3</title>
|
||||
<path
|
||||
id="path8172"
|
||||
d="m 284.39,-21 c 9.718,0 22.121,0 33.457,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000" />
|
||||
<polygon
|
||||
id="polygon8174"
|
||||
points="317.85,-24.5001 317.85,-24.5001 327.85,-21 317.85,-17.5001 "
|
||||
style="fill:#000000;stroke:#000000" />
|
||||
<text
|
||||
id="text8176"
|
||||
font-size="14.00"
|
||||
y="-24.799999"
|
||||
x="306"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">o</text>
|
||||
</g>
|
||||
<g
|
||||
transform="matrix(1.25,0,0,1.25,22.058443,108.42284)"
|
||||
class="edge"
|
||||
id="edge4">
|
||||
<title
|
||||
id="title8179">2->2</title>
|
||||
<path
|
||||
id="path8181"
|
||||
d="M 258.969,-37.6641 C 257.406,-47.625 259.75,-57 266,-57 c 4.004,0 6.405,3.8475 7.202,9.2318"
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000" />
|
||||
<polygon
|
||||
id="polygon8183"
|
||||
points="276.7,-47.6033 276.7,-47.6033 273.031,-37.6641 269.701,-47.7219 "
|
||||
style="fill:#000000;stroke:#000000" />
|
||||
<text
|
||||
id="text8185"
|
||||
font-size="14.00"
|
||||
y="-60.799999"
|
||||
x="266"
|
||||
style="font-size:14px;text-anchor:middle;font-family:'Times,serif'">t</text>
|
||||
</g>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:italic;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr"
|
||||
x="70.90358"
|
||||
y="164.58513"
|
||||
id="text8322"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="70.90358"
|
||||
y="164.58513"
|
||||
id="tspan8326">Initial state </tspan></text>
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-3);fill-opacity:1"
|
||||
d="m 116.65749,146.6479 0,-47.142861"
|
||||
id="path8330"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:italic;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr"
|
||||
x="377.5318"
|
||||
y="164.58513"
|
||||
id="text8322-2"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="377.5318"
|
||||
y="164.58513"
|
||||
id="tspan8326-7">final state </tspan></text>
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-3);fill-opacity:1"
|
||||
d="m 417.79352,146.64791 0,-47.142858"
|
||||
id="path8330-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:italic;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr"
|
||||
x="225.24609"
|
||||
y="164.58513"
|
||||
id="text8322-6"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="225.24609"
|
||||
y="164.58513"
|
||||
id="tspan8326-8">transition</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="225.24609"
|
||||
y="176.61113"
|
||||
id="tspan3049"
|
||||
style="font-size:8px;fill:#000000;fill-opacity:1;-inkscape-font-specification:Sans Italic;font-family:Sans;font-weight:normal;font-style:italic;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr;line-height:125%">(with symbols, i.e. letters)</tspan></text>
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-3);fill-opacity:1"
|
||||
d="m 262.91406,146.6479 0,-47.142861"
|
||||
id="path8330-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:italic;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Italic;font-stretch:normal;font-variant:normal;text-anchor:start;text-align:start;writing-mode:lr"
|
||||
x="193.36186"
|
||||
y="-10.2211"
|
||||
id="text8322-4"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
x="193.36186"
|
||||
y="-10.2211"
|
||||
id="tspan8326-73">state</tspan></text>
|
||||
<path
|
||||
style="fill:#000000;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend-3);fill-opacity:1"
|
||||
d="m 213.83006,-4.21356 0,47.14286"
|
||||
id="path8330-55"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 15 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/challenge.png
Normal file
|
After Width: | Height: | Size: 54 KiB |
796
web_src/05_Lectures/00_Computers/unix/images/command-grep1.svg
Normal file
@@ -0,0 +1,796 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="624.34357"
|
||||
height="392.31509"
|
||||
id="svg3015"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="command-grep1.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1617"
|
||||
inkscape:window-height="1026"
|
||||
id="namedview3346"
|
||||
showgrid="false"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="0.70599707"
|
||||
inkscape:cx="-223.24901"
|
||||
inkscape:cy="168.63465"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3015" />
|
||||
<defs
|
||||
id="defs3017">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119"
|
||||
id="linearGradient3840"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,413.43266,834.48764)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121"
|
||||
id="linearGradient3842"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,413.43266,834.48764)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115"
|
||||
id="linearGradient3837"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,412.81896,832.92554)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100"
|
||||
id="linearGradient3822"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,413.51976,835.34494)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097"
|
||||
id="linearGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,414.00426,837.79994)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091"
|
||||
id="radialGradient3813"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,415.93756,842.67194)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093"
|
||||
id="linearGradient3815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,415.93756,842.44794)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119-7"
|
||||
id="linearGradient3840-7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,638.64606,743.83574)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119-7">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208-4" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210-7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121-2"
|
||||
id="linearGradient3842-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,638.64606,743.83574)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121-2">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178-6" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180-1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115-7"
|
||||
id="linearGradient3837-3"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,638.03236,742.27364)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115-7">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256-3" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258-8" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100-5"
|
||||
id="linearGradient3822-9"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,638.73316,744.69304)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100-5">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240-5" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242-7" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097-5"
|
||||
id="linearGradient3819-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,639.21766,747.14804)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097-5">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669-9" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671-4" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091-1"
|
||||
id="radialGradient3813-1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,641.15096,752.02004)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091-1">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449-2" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451-0" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093-5"
|
||||
id="linearGradient3815-9"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,641.15096,751.79604)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093-5">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216-1" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218-8" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793"
|
||||
y="160.70892"
|
||||
x="309.23102"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795"
|
||||
y="160.70892"
|
||||
x="309.23102">grep</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826"
|
||||
y="314.1124"
|
||||
x="319.91125"><tspan
|
||||
id="tspan3828"
|
||||
y="314.1124"
|
||||
x="319.91125" /></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3830"
|
||||
d="m 176.06044,98.45559 0,10.59374 -37.8125,0 0,20 37.8125,0 0,9.1875 34.40625,-19.875 -34.40625,-19.90624 z" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837"
|
||||
y="99.112427"
|
||||
x="4.21875"><tspan
|
||||
id="tspan3839"
|
||||
y="99.112427"
|
||||
x="4.21875">-B 2 root /etc/passwd</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837-2"
|
||||
y="0.43497011"
|
||||
x="326.21149"><tspan
|
||||
id="tspan3839-7"
|
||||
y="0.43497011"
|
||||
x="326.21149" /></text>
|
||||
<path
|
||||
id="path3029-8"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 429.11365,260.24493 24.30925,-0.0113 0,25.5 64.625,-37.28125 -64.625,-37.3125 0,25.5 -24.30925,-0.0679 c 0,0 -17.5031,0.78696 -15.54079,-33.01333 l 84.0162,-0.3399 0,-108.71874 -140.0625,0 0,-44.84375 25.5,-44.15626 -74.59375,0 25.5,44.18751 0,44.8125 -140.0625,0 0,9.4375 25.125,14.49999 -25.125,14.5 0,70.28125 140.0625,0 0,24.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-24.375 33.03326,0.15674 c -0.4583,59.01777 38.55383,56.86944 38.55383,56.86944 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
|
||||
<g
|
||||
transform="translate(92.85607,-139.96108)"
|
||||
id="g3844">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840);fill-rule:evenodd;stroke:url(#linearGradient3842);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813);fill-rule:evenodd;stroke:url(#linearGradient3815);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-132.35733,-49.30914)"
|
||||
id="g3844-8">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840-7);fill-rule:evenodd;stroke:url(#linearGradient3842-4);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316-5" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837-3);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314-6" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345-6" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264-2" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266-2" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268-3" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270-9" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272-6" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274-9" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276-0" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278-9" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280-8" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282-5" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284-9" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822-9);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232-9" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819-0);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443-3" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340-6" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813-1);fill-rule:evenodd;stroke:url(#linearGradient3815-9);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025-6" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458-3" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300-2" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174-5">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124-9"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 29 KiB |
838
web_src/05_Lectures/00_Computers/unix/images/command-grep2.svg
Normal file
@@ -0,0 +1,838 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="525.73773"
|
||||
height="529.5658"
|
||||
id="svg3015"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="command-grep2.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1617"
|
||||
inkscape:window-height="1026"
|
||||
id="namedview18"
|
||||
showgrid="false"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="0.76833867"
|
||||
inkscape:cx="-3.4419283"
|
||||
inkscape:cy="65.672718"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3015" />
|
||||
<defs
|
||||
id="defs3017">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119"
|
||||
id="linearGradient3840"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,512.03848,700.29373)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121"
|
||||
id="linearGradient3842"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,512.03848,700.29373)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115"
|
||||
id="linearGradient3837"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,511.42478,698.73163)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100"
|
||||
id="linearGradient3822"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,512.12558,701.15103)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097"
|
||||
id="linearGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,512.61008,703.60603)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091"
|
||||
id="radialGradient3813"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,514.54338,708.47803)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093"
|
||||
id="linearGradient3815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,514.54338,708.25403)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119-1"
|
||||
id="linearGradient3840-9"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,737.19964,606.58505)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119-1">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208-6" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210-8" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121-9"
|
||||
id="linearGradient3842-6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,737.19964,606.58505)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121-9">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178-6" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180-5" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115-4"
|
||||
id="linearGradient3837-7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,736.58594,605.02295)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115-4">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256-3" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258-1" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100-6"
|
||||
id="linearGradient3822-6"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,737.28674,607.44235)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100-6">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240-0" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242-2" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097-3"
|
||||
id="linearGradient3819-7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,737.77124,609.89735)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097-3">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669-4" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671-7" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091-3"
|
||||
id="radialGradient3813-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,739.70454,614.76935)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091-3">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449-6" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451-3" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093-4"
|
||||
id="linearGradient3815-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,739.70454,614.54535)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093-4">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216-8" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218-4" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826"
|
||||
y="449.71979"
|
||||
x="222.05412"><tspan
|
||||
id="tspan3828"
|
||||
y="449.71979"
|
||||
x="222.05412" /></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793"
|
||||
y="296.31631"
|
||||
x="211.37389"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795"
|
||||
y="296.31631"
|
||||
x="211.37389">grep</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3830"
|
||||
d="m 78.20329,234.06296 0,10.59375 -37.812502,0 0,20 37.812502,0 0,9.1875 34.40625,-19.875 -34.40625,-19.90625 z" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837"
|
||||
y="234.7198"
|
||||
x="4.21875"><tspan
|
||||
id="tspan3839"
|
||||
y="234.7198"
|
||||
x="4.21875">-B 2 root</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837-2"
|
||||
y="136.04234"
|
||||
x="228.35435"><tspan
|
||||
id="tspan3839-7"
|
||||
y="136.04234"
|
||||
x="228.35435" /></text>
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path72"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 265.76775,6.1260426 h -49.54587 a 2.2520851,2.2520851 0 0 0 -2.25209,2.25208 V 87.201105 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 65.31047 a 2.2520851,2.2520851 0 0 0 2.25208,-2.252085 V 24.142722" />
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path74"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 224.10418,53.419828 h 49.54587 m -49.54587,20.268766 h 38.28544 m -38.28544,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587 m -49.54587,-13.51251 h 49.54587 m -49.54587,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587" />
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path76"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 265.76775,6.1260426 V 21.890637 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 15.76459 z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="166.44937"
|
||||
y="126.15913"
|
||||
id="text3390"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3392"
|
||||
x="166.44937"
|
||||
y="126.15913"
|
||||
style="font-size:28px">/etc/passwd</tspan></text>
|
||||
<g
|
||||
id="g3544"
|
||||
transform="translate(-464.71223,-136.08718)">
|
||||
<text
|
||||
x="676.08612"
|
||||
y="432.40347"
|
||||
id="text3793-3"
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
x="676.08612"
|
||||
y="432.40347"
|
||||
id="tspan3795-0"
|
||||
style="font-size:32px">grep</tspan></text>
|
||||
<path
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 795.96873,531.93949 24.30925,-0.0113 0,25.5 64.625,-37.28125 -64.625,-37.3125 0,25.5 -24.30925,-0.0679 c 0,0 -17.5031,0.78696 -15.54079,-33.01333 l 84.0162,-0.3399 0,-108.71874 -140.0625,0 0,-44.84376 25.5,-44.15625 -74.59375,0 25.5,44.1875 0,44.81251 -140.0625,0 0,9.4375 25.125,14.49999 -25.125,14.5 0,70.28125 140.0625,0 0,24.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-24.375 33.03326,0.15674 c -0.4583,59.01777 38.55383,56.86944 38.55383,56.86944 z"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="path3029-8" />
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-5.7497821,-5.7671334)"
|
||||
id="g3844">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840);fill-rule:evenodd;stroke:url(#linearGradient3842);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813);fill-rule:evenodd;stroke:url(#linearGradient3815);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-230.91091,87.941545)"
|
||||
id="g3844-1">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840-9);fill-rule:evenodd;stroke:url(#linearGradient3842-6);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316-7" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837-7);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314-1" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345-0" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264-1" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266-7" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268-0" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270-9" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272-9" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274-6" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276-6" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278-6" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280-0" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282-9" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284-7" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822-6);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232-6" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819-7);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443-7" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340-0" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813-0);fill-rule:evenodd;stroke:url(#linearGradient3815-0);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025-1" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458-6" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300-3" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174-5">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124-3"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126-5"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 31 KiB |
622
web_src/05_Lectures/00_Computers/unix/images/command-grep3.svg
Normal file
@@ -0,0 +1,622 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="531.48755"
|
||||
height="560.87561"
|
||||
id="svg3015"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="command-grep3.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1617"
|
||||
inkscape:window-height="1026"
|
||||
id="namedview16"
|
||||
showgrid="false"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="0.72379263"
|
||||
inkscape:cx="8.715299"
|
||||
inkscape:cy="260.7416"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3015" />
|
||||
<defs
|
||||
id="defs3017">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451" />
|
||||
</radialGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091"
|
||||
id="radialGradient3813"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,508.79363,702.71087)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093"
|
||||
id="linearGradient3815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,508.79363,702.48687)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097"
|
||||
id="linearGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,506.86033,697.83887)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100"
|
||||
id="linearGradient3822"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,506.37583,695.38386)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115"
|
||||
id="linearGradient3837"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,505.67503,692.96445)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119"
|
||||
id="linearGradient3840"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,506.28873,694.52656)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121"
|
||||
id="linearGradient3842"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,506.28873,694.52656)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119"
|
||||
id="linearGradient3931"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,506.28873,694.52656)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121"
|
||||
id="linearGradient3933"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,506.28873,694.52656)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115"
|
||||
id="linearGradient3935"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,505.67503,692.96445)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100"
|
||||
id="linearGradient3937"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,506.37583,695.38386)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097"
|
||||
id="linearGradient3939"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,506.86033,697.83887)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091"
|
||||
id="radialGradient3941"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,508.79363,702.71087)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093"
|
||||
id="linearGradient3943"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,508.79363,702.48687)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826"
|
||||
y="449.08658"
|
||||
x="244.7636"><tspan
|
||||
id="tspan3828"
|
||||
y="449.08658"
|
||||
x="244.7636" /></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837-2"
|
||||
y="135.40916"
|
||||
x="251.06383"><tspan
|
||||
id="tspan3839-7"
|
||||
y="135.40916"
|
||||
x="251.06383" /></text>
|
||||
<g
|
||||
id="g4132"
|
||||
transform="translate(14.003209,4.3626552)">
|
||||
<g
|
||||
id="g70-6"
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:1;stroke-linecap:round;stroke-linejoin:round"
|
||||
transform="matrix(2.2520851,0,0,2.2520851,180.82386,419.99839)">
|
||||
<path
|
||||
id="path72-7-7"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 31.5,5.5 h -22 a 1,1 0 0 0 -1,1 v 35 a 1,1 0 0 0 1,1 h 29 a 1,1 0 0 0 1,-1 v -28"
|
||||
style="stroke-width:1" />
|
||||
<path
|
||||
id="path74-5-6"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 13,26.5 h 22 m -22,9 h 17 m -17,-3 h 22 m -22,-3 h 22 m -22,-6 h 22 m -22,-3 h 22 m -22,-3 h 22"
|
||||
style="stroke-width:1" />
|
||||
<path
|
||||
id="path76-6-6"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 31.5,5.5 v 7 a 1,1 0 0 0 1,1 h 7 z"
|
||||
style="stroke-width:1" />
|
||||
</g>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3390-6-7"
|
||||
y="551.11646"
|
||||
x="194.29578"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:28px"
|
||||
y="551.11646"
|
||||
x="194.29578"
|
||||
id="tspan3392-4-9"
|
||||
sodipodi:role="line">result</tspan></text>
|
||||
</g>
|
||||
<g
|
||||
id="g4112">
|
||||
<text
|
||||
x="222.05412"
|
||||
y="449.71979"
|
||||
id="text3826-8"
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
x="222.05412"
|
||||
y="449.71979"
|
||||
id="tspan3828-4" /></text>
|
||||
<text
|
||||
x="211.37389"
|
||||
y="296.31631"
|
||||
id="text3793"
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
x="211.37389"
|
||||
y="296.31631"
|
||||
id="tspan3795"
|
||||
style="font-size:32px">grep</tspan></text>
|
||||
<path
|
||||
d="m 78.20329,234.06296 0,10.59375 -37.812502,0 0,20 37.812502,0 0,9.1875 34.40625,-19.875 -34.40625,-19.90625 z"
|
||||
id="path3830"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
x="4.21875"
|
||||
y="234.7198"
|
||||
id="text3837"
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
x="4.21875"
|
||||
y="234.7198"
|
||||
id="tspan3839">-B 2 root</tspan></text>
|
||||
<text
|
||||
x="228.35435"
|
||||
y="136.04234"
|
||||
id="text3837-2-6"
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
x="228.35435"
|
||||
y="136.04234"
|
||||
id="tspan3839-7-3" /></text>
|
||||
<path
|
||||
d="m 265.76775,6.1260426 h -49.54587 a 2.2520851,2.2520851 0 0 0 -2.25209,2.25208 V 87.201105 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 65.31047 a 2.2520851,2.2520851 0 0 0 2.25208,-2.252085 V 24.142722"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path72"
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round" />
|
||||
<path
|
||||
d="m 224.10418,53.419828 h 49.54587 m -49.54587,20.268766 h 38.28544 m -38.28544,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587 m -49.54587,-13.51251 h 49.54587 m -49.54587,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path74"
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round" />
|
||||
<path
|
||||
d="M 265.76775,6.1260426 V 21.890637 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 15.76459 z"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path76"
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text3390"
|
||||
y="126.15913"
|
||||
x="166.44937"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"><tspan
|
||||
style="font-size:28px"
|
||||
y="126.15913"
|
||||
x="166.44937"
|
||||
id="tspan3392"
|
||||
sodipodi:role="line">/etc/passwd</tspan></text>
|
||||
<g
|
||||
transform="translate(-464.71223,-136.08718)"
|
||||
id="g3544">
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793-3"
|
||||
y="432.40347"
|
||||
x="676.08612"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795-0"
|
||||
y="432.40347"
|
||||
x="676.08612">grep</tspan></text>
|
||||
<path
|
||||
id="path3029-8"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 795.96873,531.93949 24.30925,-0.0113 0,25.5 64.625,-37.28125 -64.625,-37.3125 0,25.5 -24.30925,-0.0679 c 0,0 -17.5031,0.78696 -15.54079,-33.01333 l 84.0162,-0.3399 0,-108.71874 -140.0625,0 0,-44.84376 25.5,-44.15625 -74.59375,0 25.5,44.1875 0,44.81251 -140.0625,0 0,9.4375 25.125,14.49999 -25.125,14.5 0,70.28125 140.0625,0 0,24.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-24.375 33.03326,0.15674 c -0.4583,59.01777 38.55383,56.86944 38.55383,56.86944 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
id="g3844">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3931);fill-rule:evenodd;stroke:url(#linearGradient3933);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3935);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3937);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3939);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3941);fill-rule:evenodd;stroke:url(#linearGradient3943);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,836 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="475.45493"
|
||||
height="801.90924"
|
||||
id="svg3015"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="command-grepless.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1280"
|
||||
inkscape:window-height="1000"
|
||||
id="namedview16"
|
||||
showgrid="false"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="1.944426"
|
||||
inkscape:cx="331.76899"
|
||||
inkscape:cy="222.83951"
|
||||
inkscape:window-x="1680"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3015"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true" />
|
||||
<defs
|
||||
id="defs3017">
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119"
|
||||
id="linearGradient3840"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,562.32132,334.24158)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121"
|
||||
id="linearGradient3842"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,562.32132,334.24158)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115"
|
||||
id="linearGradient3837"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,561.70762,332.67948)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100"
|
||||
id="linearGradient3822"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,562.40842,335.09888)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097"
|
||||
id="linearGradient3819"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,562.89292,337.55388)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091"
|
||||
id="radialGradient3813"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,564.82622,342.42588)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093"
|
||||
id="linearGradient3815"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,564.82622,342.20188)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3119-1"
|
||||
id="linearGradient3840-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,738.68708,334.24158)"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
x2="24.841999"
|
||||
y2="14.158" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.870001"
|
||||
y1="32.285999"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="24.841999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119-1">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208-9" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210-0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3121-9"
|
||||
id="linearGradient3842-7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.66502001,0,0,0.76321002,738.68708,334.24158)"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
x2="21.305"
|
||||
y2="32.498001" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6528997"
|
||||
y1="9.5865002"
|
||||
gradientTransform="matrix(0.22934017,0,0,0.26320218,28.909456,132.72537)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498001"
|
||||
id="linearGradient3121-9">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178-6" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180-9" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3115-8"
|
||||
id="linearGradient3837-9"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.6919,0,0,0.87742,738.07338,332.67948)"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
x2="26.177999"
|
||||
y2="30.343" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463003"
|
||||
gradientTransform="matrix(0.23861006,0,0,0.30258887,28.697815,132.18666)"
|
||||
x2="26.177999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115-8">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256-1" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258-0" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3100-2"
|
||||
id="linearGradient3822-7"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.65843001,0,0,0.75971001,738.77418,335.09888)"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
x2="48.845001"
|
||||
y2="49.730999" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339001"
|
||||
y1="19.636999"
|
||||
gradientTransform="matrix(0.22706753,0,0,0.26199516,28.939494,133.02102)"
|
||||
x2="48.845001"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.730999"
|
||||
id="linearGradient3100-2">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240-1" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242-6" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3097-0"
|
||||
id="linearGradient3819-0"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.76116001,0,0,0.61687,739.25868,337.55388)"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
x2="17.198999"
|
||||
y2="26.729" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.26249521,0,0,0.21273506,29.10658,133.86766)"
|
||||
x2="17.198999"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097-0">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669-4" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671-1" />
|
||||
</linearGradient>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#radialGradient3091-2"
|
||||
id="radialGradient3813-1"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60259,741.19198,342.42588)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
r="2.51" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.20781043,29.773301,135.54783)"
|
||||
cx="37.495998"
|
||||
cy="39.509998"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091-2">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449-9" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451-9" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient3093-0"
|
||||
id="linearGradient3815-4"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.60109001,0,0,0.60828002,741.19198,342.20188)"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
x2="36.452"
|
||||
y2="38" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.252998"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.20729314,0,0,0.2097727,29.773301,135.47058)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093-0">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216-7" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218-7" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793"
|
||||
y="296.31631"
|
||||
x="211.37389"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795"
|
||||
y="296.31631"
|
||||
x="211.37389">grep</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826"
|
||||
y="449.71979"
|
||||
x="222.05412"><tspan
|
||||
id="tspan3828"
|
||||
y="449.71979"
|
||||
x="222.05412" /></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3830"
|
||||
d="m 78.20329,234.06296 0,10.59375 -37.812502,0 0,20 37.812502,0 0,9.1875 34.40625,-19.875 -34.40625,-19.90625 z" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837"
|
||||
y="234.7198"
|
||||
x="4.21875"><tspan
|
||||
id="tspan3839"
|
||||
y="234.7198"
|
||||
x="4.21875">-B 2 root</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837-2"
|
||||
y="136.04234"
|
||||
x="228.35435"><tspan
|
||||
id="tspan3839-7"
|
||||
y="136.04234"
|
||||
x="228.35435" /></text>
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path72"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 265.76774,6.1260426 h -49.54587 a 2.2520851,2.2520851 0 0 0 -2.25209,2.25208 V 87.201105 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 65.31047 a 2.2520851,2.2520851 0 0 0 2.25208,-2.252085 V 24.142722" />
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path74"
|
||||
inkscape:connector-curvature="0"
|
||||
d="m 224.10418,53.419828 h 49.54587 m -49.54587,20.268766 h 38.28544 m -38.28544,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587 m -49.54587,-13.51251 h 49.54587 m -49.54587,-6.756255 h 49.54587 m -49.54587,-6.756256 h 49.54587" />
|
||||
<path
|
||||
style="fill:#f4f6f8;stroke:#0f2d59;stroke-width:2.25208521;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="path76"
|
||||
inkscape:connector-curvature="0"
|
||||
d="M 265.76774,6.1260426 V 21.890637 a 2.2520851,2.2520851 0 0 0 2.25209,2.252085 h 15.76459 z" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
x="166.44937"
|
||||
y="126.15911"
|
||||
id="text3390"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan3392"
|
||||
x="166.44937"
|
||||
y="126.15911"
|
||||
style="font-size:28px">/etc/passwd</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793-5"
|
||||
y="518.59955"
|
||||
x="216.10045"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795-3"
|
||||
y="518.59955"
|
||||
x="216.10045">less</tspan></text>
|
||||
<path
|
||||
id="path3029-8-8-1-2"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 259.67834,338.83043 33.03125,0.15625 c -0.4583,59.01777 38.5625,56.875 38.5625,56.875 l 24.34375,0 24,-0.0625 c 33.4582,-2.01645 32.65625,15.5 32.65625,15.5 l 0.0625,188.625 c -7.78226,-7.452 -37.97582,-5.82353 -83.44115,-6.10036 -2.06615,-0.007 -14.87799,-3.40598 -13.18385,-32.58709 l 84.03125,-0.3125 0,-108.71875 -140.0625,0 0,-44.84375 25.53125,-44.21875 -25.53125,0.0625 z m 152.52779,299.58089 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0.15966,-227.11214 c 0,0 2.1465,-39.03462 -56.4375,-38.8125 l -23.90625,-0.25 -24.34375,-0.0625 c 0,0 -17.52481,0.80029 -15.5625,-33 l 84.03125,-0.34375 0,-108.71875 -140.0625,0 0,-44.84375 25.5,-44.15625 -74.5937,0 25.5,44.1875 0,44.8125 -140.062504,0 0,9.4375 25.125004,14.5 -25.125004,14.5 0,70.28125 140.062504,0 -0.46875,23.90625 -25.15625,0 25.625,44.65625 0,44.8125 -140.062504,0 0,9.4375 25.125004,14.5 -25.125004,14.5 0,70.28125 140.062504,0 0,76.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-76.375 33.03125,0.15625 c -0.4583,59.01777 38.5625,56.84375 38.5625,56.84375 24.86625,0.69813 47.56812,0.15993 66.8125,0.96875 7.99927,0.34787 14.07812,19.46255 14.07812,19.46255"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" />
|
||||
<g
|
||||
transform="translate(-56.032592,360.28501)"
|
||||
id="g3844">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840);fill-rule:evenodd;stroke:url(#linearGradient3842);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813);fill-rule:evenodd;stroke:url(#linearGradient3815);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
<g
|
||||
transform="translate(-232.39835,360.28501)"
|
||||
id="g3844-7">
|
||||
<rect
|
||||
x="435.48694"
|
||||
y="345.62366"
|
||||
width="90.627541"
|
||||
height="90.627541"
|
||||
ry="3.8882"
|
||||
rx="3.3699999"
|
||||
style="fill:url(#linearGradient3840-0);fill-rule:evenodd;stroke:url(#linearGradient3842-7);stroke-width:0.74608999;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316-3" />
|
||||
<rect
|
||||
x="443.58554"
|
||||
y="352.31619"
|
||||
width="74.589241"
|
||||
height="74.589241"
|
||||
ry="1.4582"
|
||||
rx="1.1411"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3837-9);stroke-width:0.78010005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314-2" />
|
||||
<path
|
||||
d="m 449.05728,364.21081 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path1345-8" />
|
||||
<path
|
||||
d="m 449.05728,368.85904 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2264-6" />
|
||||
<path
|
||||
d="m 449.05728,373.50728 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2266-3" />
|
||||
<path
|
||||
d="m 449.05728,378.15551 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2268-0" />
|
||||
<path
|
||||
d="m 449.05728,382.80375 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2270-4" />
|
||||
<path
|
||||
d="m 449.05728,387.44908 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2272-3" />
|
||||
<path
|
||||
d="m 449.05728,392.09732 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2274-9" />
|
||||
<path
|
||||
d="m 449.05728,396.74555 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2276-5" />
|
||||
<path
|
||||
d="m 449.05728,401.39379 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2278-4" />
|
||||
<path
|
||||
d="m 449.05728,406.04202 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2280-7" />
|
||||
<path
|
||||
d="m 449.05728,410.69026 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2282-8" />
|
||||
<path
|
||||
d="m 449.05728,415.3356 h 63.73853"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.74273002"
|
||||
id="path2284-4" />
|
||||
<rect
|
||||
x="437.60199"
|
||||
y="347.94052"
|
||||
width="85.990906"
|
||||
height="85.990906"
|
||||
ry="3.0385001"
|
||||
rx="2.6178"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3822-7);stroke-width:0.74394;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232-6" />
|
||||
<path
|
||||
d="m 451.72356,357.71836 c -0.93431,0 -2.8101,0.37965 -2.8101,2.04812 l 0.21076,32.9726 c 31.55175,-1.92251 25.21994,-16.47905 63.97341,-23.77182 l 0.29896,-9.89903 c -0.13974,-2.246 -1.37391,-1.22783 -3.28595,-1.21463 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3819-0);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443-0" />
|
||||
<rect
|
||||
x="446.86221"
|
||||
y="355.70886"
|
||||
width="68.273674"
|
||||
height="68.273674"
|
||||
ry="0.10638001"
|
||||
rx="0.081467003"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.58150005;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340-7" />
|
||||
<rect
|
||||
x="503.63419"
|
||||
y="427.06201"
|
||||
width="7.0068593"
|
||||
height="7.0080194"
|
||||
ry="0.45756"
|
||||
rx="0.21531001"
|
||||
style="fill:url(#radialGradient3813-1);fill-rule:evenodd;stroke:url(#linearGradient3815-4);stroke-width:0.70067;stroke-linecap:round"
|
||||
id="rect5025-5" />
|
||||
<rect
|
||||
x="505.13043"
|
||||
y="428.3988"
|
||||
width="4.0294371"
|
||||
height="4.0294371"
|
||||
ry="0.38924003"
|
||||
rx="0.38924003"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458-1" />
|
||||
<path
|
||||
sodipodi:cx="28.3125"
|
||||
sodipodi:cy="38.75"
|
||||
transform="matrix(1.750642,0,0,1.7640386,456.91984,361.2734)"
|
||||
d="m 28.875,38.75 c 0,0.31066 -0.25184,0.5625 -0.5625,0.5625 -0.31066,0 -0.5625,-0.25184 -0.5625,-0.5625 0,-0.31066 0.25184,-0.5625 0.5625,-0.5625 0.31066,0 0.5625,0.25184 0.5625,0.5625 z"
|
||||
sodipodi:type="arc"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
sodipodi:ry="0.5625"
|
||||
sodipodi:rx="0.5625"
|
||||
id="path2300-9" />
|
||||
<g
|
||||
transform="matrix(2.9014499,0,0,2.8979413,422.45969,309.66146)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="text3174-9">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 v 0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3124-4"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 h 7.4635 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.11052829"
|
||||
id="path3126-1"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 31 KiB |
120
web_src/05_Lectures/00_Computers/unix/images/command.svg
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="487.70905"
|
||||
height="336.06024"
|
||||
id="svg3015"
|
||||
inkscape:version="0.48.4 r9939"
|
||||
sodipodi:docname="command.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1156"
|
||||
inkscape:window-height="675"
|
||||
id="namedview16"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="0.51179868"
|
||||
inkscape:cx="520.03009"
|
||||
inkscape:cy="123.32603"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="0"
|
||||
inkscape:current-layer="svg3015" />
|
||||
<defs
|
||||
id="defs3017" />
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3793"
|
||||
y="177.43022"
|
||||
x="171.70871"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795"
|
||||
y="177.43022"
|
||||
x="171.70871">command</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826"
|
||||
y="330.83368"
|
||||
x="225.31082"><tspan
|
||||
id="tspan3828"
|
||||
y="330.83368"
|
||||
x="225.31082">stdout</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"
|
||||
id="path3830"
|
||||
d="m 81.459988,115.17687 0,10.59375 -37.8125,0 0,20 37.8125,0 0,9.1875 34.406252,-19.875 -34.406252,-19.90625 z" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837"
|
||||
y="113.69086"
|
||||
x="3.546875"><tspan
|
||||
id="tspan3839"
|
||||
y="113.69086"
|
||||
x="3.546875">parameters</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3837-2"
|
||||
y="17.15625"
|
||||
x="231.61105"><tspan
|
||||
id="tspan3839-7"
|
||||
y="17.15625"
|
||||
x="231.61105">stdin</tspan></text>
|
||||
<path
|
||||
id="path3029-8"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 334.42861,276.88163 24.30925,-0.0113 0,25.5 64.625,-37.28125 -64.625,-37.3125 0,25.5 -24.30925,-0.0679 c 0,0 -17.5031,0.78696 -15.54079,-33.01333 l 84.0162,-0.3399 0,-108.71875 -140.0625,0 0,-44.843753 25.5,-44.15625 -74.59375,0 25.5,44.1875 0,44.812503 -140.062502,0 0,9.4375 25.125002,14.5 -25.125002,14.5 0,70.28125 140.062502,0 0,24.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-24.375 33.03326,0.15674 c -0.4583,59.01777 38.55383,56.86944 38.55383,56.86944 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-size:16px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
|
||||
xml:space="preserve"
|
||||
id="text3826-6"
|
||||
y="270.01694"
|
||||
x="435.19342"><tspan
|
||||
id="tspan3828-4"
|
||||
y="270.01694"
|
||||
x="435.19342">stderr</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.6 KiB |
14
web_src/05_Lectures/00_Computers/unix/images/exp1.dot
Normal file
@@ -0,0 +1,14 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 3;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "t" ];
|
||||
1 -> 2 [ label = "o" ];
|
||||
2 -> 2 [ label = "t" ];
|
||||
2 -> 3 [ label = "o" ];
|
||||
|
||||
}
|
||||
64
web_src/05_Lectures/00_Computers/unix/images/exp1.svg
Normal file
@@ -0,0 +1,64 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="380pt" height="80pt"
|
||||
viewBox="0.00 0.00 380.00 80.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 76)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-76 376,-76 376,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-17.3" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-21C62.8864,-21 72.746,-21 81.6534,-21"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-24.5001 91.9117,-21 81.9117,-17.5001 81.9117,-24.5001"/>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node2" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="350" cy="-21" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="350" cy="-21" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="350" y="-17.3" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="186" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="186" y="-17.3" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.163,-21C136.942,-21 147.837,-21 157.733,-21"/>
|
||||
<polygon fill="black" stroke="black" points="157.93,-24.5001 167.93,-21 157.93,-17.5001 157.93,-24.5001"/>
|
||||
<text text-anchor="middle" x="148" y="-24.8" font-family="Times,serif" font-size="14.00">t</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="266" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="266" y="-17.3" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge3" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M204.311,-21C214.106,-21 226.578,-21 237.665,-21"/>
|
||||
<polygon fill="black" stroke="black" points="237.738,-24.5001 247.738,-21 237.738,-17.5001 237.738,-24.5001"/>
|
||||
<text text-anchor="middle" x="226" y="-24.8" font-family="Times,serif" font-size="14.00">o</text>
|
||||
</g>
|
||||
<!-- 2->3 -->
|
||||
<g id="edge5" class="edge"><title>2->3</title>
|
||||
<path fill="none" stroke="black" d="M284.39,-21C294.108,-21 306.511,-21 317.847,-21"/>
|
||||
<polygon fill="black" stroke="black" points="317.85,-24.5001 327.85,-21 317.85,-17.5001 317.85,-24.5001"/>
|
||||
<text text-anchor="middle" x="306" y="-24.8" font-family="Times,serif" font-size="14.00">o</text>
|
||||
</g>
|
||||
<!-- 2->2 -->
|
||||
<g id="edge4" class="edge"><title>2->2</title>
|
||||
<path fill="none" stroke="black" d="M258.969,-37.6641C257.406,-47.625 259.75,-57 266,-57 270.004,-57 272.405,-53.1525 273.202,-47.7682"/>
|
||||
<polygon fill="black" stroke="black" points="276.7,-47.6033 273.031,-37.6641 269.701,-47.7219 276.7,-47.6033"/>
|
||||
<text text-anchor="middle" x="266" y="-60.8" font-family="Times,serif" font-size="14.00">t</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.4 KiB |
13
web_src/05_Lectures/00_Computers/unix/images/exp2.dot
Normal file
@@ -0,0 +1,13 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 3;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "A" ];
|
||||
1 -> 2 [ label = "T" ];
|
||||
2 -> 3 [ label = "G" ];
|
||||
|
||||
}
|
||||
58
web_src/05_Lectures/00_Computers/unix/images/exp2.svg
Normal file
@@ -0,0 +1,58 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="390pt" height="50pt"
|
||||
viewBox="0.00 0.00 390.00 50.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 46)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-46 386,-46 386,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-17.3" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-21C62.8864,-21 72.746,-21 81.6534,-21"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-24.5001 91.9117,-21 81.9117,-17.5001 81.9117,-24.5001"/>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node2" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-21" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-21" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="360" y="-17.3" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="192" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="192" y="-17.3" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.359,-21C138.703,-21 152.059,-21 163.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="163.95,-24.5001 173.95,-21 163.95,-17.5001 163.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="151" y="-24.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-17.3" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge3" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M210.359,-21C220.703,-21 234.059,-21 245.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="245.95,-24.5001 255.95,-21 245.95,-17.5001 245.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="233" y="-24.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2->3 -->
|
||||
<g id="edge4" class="edge"><title>2->3</title>
|
||||
<path fill="none" stroke="black" d="M292.405,-21C302.589,-21 315.751,-21 327.682,-21"/>
|
||||
<polygon fill="black" stroke="black" points="327.744,-24.5001 337.744,-21 327.744,-17.5001 327.744,-24.5001"/>
|
||||
<text text-anchor="middle" x="315" y="-24.8" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
15
web_src/05_Lectures/00_Computers/unix/images/exp3.dot
Normal file
@@ -0,0 +1,15 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 3;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "A" ];
|
||||
0 -> 1 [ label = "T" ];
|
||||
0 -> 1 [ label = "G" ];
|
||||
1 -> 2 [ label = "T" ];
|
||||
2 -> 3 [ label = "G" ];
|
||||
|
||||
}
|
||||
70
web_src/05_Lectures/00_Computers/unix/images/exp3.svg
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="390pt" height="63pt"
|
||||
viewBox="0.00 0.00 390.00 63.22" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 59.22)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-59.22 386,-59.22 386,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-24.22" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-20.52" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-24.22C62.8864,-24.22 72.746,-24.22 81.6534,-24.22"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-27.7201 91.9117,-24.22 81.9117,-20.7201 81.9117,-27.7201"/>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node2" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-24.22" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-24.22" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="360" y="-20.52" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="192" cy="-24.22" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="192" y="-20.52" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M126.184,-32.8802C132.161,-35.8239 139.211,-38.7417 146,-40.22 153.076,-41.7608 160.562,-40.3877 167.355,-37.9096"/>
|
||||
<polygon fill="black" stroke="black" points="169.007,-41.0038 176.682,-33.6992 166.127,-34.6237 169.007,-41.0038"/>
|
||||
<text text-anchor="middle" x="151" y="-44.02" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge3" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.071,-22.4625C133.766,-21.9547 140.151,-21.4702 146,-21.22 151.769,-20.9732 157.949,-21.1176 163.824,-21.4483"/>
|
||||
<polygon fill="black" stroke="black" points="163.683,-24.9474 173.916,-22.2004 164.204,-17.9667 163.683,-24.9474"/>
|
||||
<text text-anchor="middle" x="151" y="-25.02" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge4" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M124.359,-12.7905C130.524,-8.24815 138.198,-3.55405 146,-1.22002 154.156,1.22002 162.594,-1.49387 169.929,-5.80525"/>
|
||||
<polygon fill="black" stroke="black" points="168.332,-8.96142 178.525,-11.853 172.36,-3.23635 168.332,-8.96142"/>
|
||||
<text text-anchor="middle" x="151" y="-5.02002" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-24.22" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-20.52" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge5" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M210.359,-24.22C220.703,-24.22 234.059,-24.22 245.779,-24.22"/>
|
||||
<polygon fill="black" stroke="black" points="245.95,-27.7201 255.95,-24.22 245.95,-20.7201 245.95,-27.7201"/>
|
||||
<text text-anchor="middle" x="233" y="-28.02" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2->3 -->
|
||||
<g id="edge6" class="edge"><title>2->3</title>
|
||||
<path fill="none" stroke="black" d="M292.405,-24.22C302.589,-24.22 315.751,-24.22 327.682,-24.22"/>
|
||||
<polygon fill="black" stroke="black" points="327.744,-27.7201 337.744,-24.22 327.744,-20.7201 327.744,-27.7201"/>
|
||||
<text text-anchor="middle" x="315" y="-28.02" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
16
web_src/05_Lectures/00_Computers/unix/images/exp4.dot
Normal file
@@ -0,0 +1,16 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 3;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "A" ];
|
||||
0 -> 1 [ label = "C" ];
|
||||
0 -> 1 [ label = "G" ];
|
||||
0 -> 1 [ label = "T" ];
|
||||
1 -> 2 [ label = "T" ];
|
||||
2 -> 3 [ label = "G" ];
|
||||
|
||||
}
|
||||
76
web_src/05_Lectures/00_Computers/unix/images/exp4.svg
Normal file
@@ -0,0 +1,76 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="390pt" height="100pt"
|
||||
viewBox="0.00 0.00 390.00 99.74" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 95.7363)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-95.7363 386,-95.7363 386,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-40.7363" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-37.0363" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-40.7363C62.8864,-40.7363 72.746,-40.7363 81.6534,-40.7363"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-44.2364 91.9117,-40.7363 81.9117,-37.2364 81.9117,-44.2364"/>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node2" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-40.7363" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-40.7363" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="360" y="-37.0363" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="192" cy="-40.7363" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="192" y="-37.0363" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M120.878,-55.0794C127.088,-62.777 135.838,-71.527 146,-75.7363 157.001,-80.2932 167.601,-72.8364 175.747,-63.6515"/>
|
||||
<polygon fill="black" stroke="black" points="178.529,-65.7767 181.968,-55.7556 173.03,-61.4449 178.529,-65.7767"/>
|
||||
<text text-anchor="middle" x="151" y="-80.5363" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge3" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.359,-40.7363C138.703,-40.7363 152.059,-40.7363 163.779,-40.7363"/>
|
||||
<polygon fill="black" stroke="black" points="163.95,-44.2364 173.95,-40.7363 163.95,-37.2364 163.95,-44.2364"/>
|
||||
<text text-anchor="middle" x="151" y="-44.5363" font-family="Times,serif" font-size="14.00">C</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge4" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M125.311,-30.8706C131.402,-27.2429 138.763,-23.5741 146,-21.7363 153.459,-19.8423 161.285,-21.6787 168.28,-24.8388"/>
|
||||
<polygon fill="black" stroke="black" points="166.742,-27.9877 177.191,-29.7424 170.117,-21.8549 166.742,-27.9877"/>
|
||||
<text text-anchor="middle" x="151" y="-25.5363" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge5" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M119.961,-25.5944C126.071,-16.8458 135.033,-6.62979 146,-1.73634 157.887,3.56771 168.966,-5.77917 177.157,-16.6487"/>
|
||||
<polygon fill="black" stroke="black" points="174.327,-18.7111 182.823,-25.04 180.128,-14.7938 174.327,-18.7111"/>
|
||||
<text text-anchor="middle" x="151" y="-5.53634" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-40.7363" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-37.0363" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge6" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M210.359,-40.7363C220.703,-40.7363 234.059,-40.7363 245.779,-40.7363"/>
|
||||
<polygon fill="black" stroke="black" points="245.95,-44.2364 255.95,-40.7363 245.95,-37.2364 245.95,-44.2364"/>
|
||||
<text text-anchor="middle" x="233" y="-44.5363" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2->3 -->
|
||||
<g id="edge7" class="edge"><title>2->3</title>
|
||||
<path fill="none" stroke="black" d="M292.405,-40.7363C302.589,-40.7363 315.751,-40.7363 327.682,-40.7363"/>
|
||||
<polygon fill="black" stroke="black" points="327.744,-44.2364 337.744,-40.7363 327.744,-37.2364 327.744,-44.2364"/>
|
||||
<text text-anchor="middle" x="315" y="-44.5363" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.4 KiB |
16
web_src/05_Lectures/00_Computers/unix/images/exp5.dot
Normal file
@@ -0,0 +1,16 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 5;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "T" ];
|
||||
1 -> 2 [ label = "T" ];
|
||||
2 -> 3 [ label = "A" ];
|
||||
3 -> 3 [ label = "A" ];
|
||||
3 -> 4 [ label = "T" ];
|
||||
4 -> 5 [ label = "T" ];
|
||||
|
||||
}
|
||||
86
web_src/05_Lectures/00_Computers/unix/images/exp5.svg
Normal file
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="554pt" height="80pt"
|
||||
viewBox="0.00 0.00 554.00 80.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 76)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-76 550,-76 550,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-17.3" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-21C62.8864,-21 72.746,-21 81.6534,-21"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-24.5001 91.9117,-21 81.9117,-17.5001 81.9117,-24.5001"/>
|
||||
</g>
|
||||
<!-- 5 -->
|
||||
<g id="node2" class="node"><title>5</title>
|
||||
<ellipse fill="none" stroke="black" cx="524" cy="-21" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="524" cy="-21" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="524" y="-17.3" font-family="Times,serif" font-size="14.00">5</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="192" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="192" y="-17.3" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.359,-21C138.703,-21 152.059,-21 163.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="163.95,-24.5001 173.95,-21 163.95,-17.5001 163.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="151" y="-24.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-17.3" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge3" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M210.359,-21C220.703,-21 234.059,-21 245.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="245.95,-24.5001 255.95,-21 245.95,-17.5001 245.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="233" y="-24.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node6" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="356" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="356" y="-17.3" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 2->3 -->
|
||||
<g id="edge4" class="edge"><title>2->3</title>
|
||||
<path fill="none" stroke="black" d="M292.359,-21C302.703,-21 316.059,-21 327.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="327.95,-24.5001 337.95,-21 327.95,-17.5001 327.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="315" y="-24.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 3->3 -->
|
||||
<g id="edge5" class="edge"><title>3->3</title>
|
||||
<path fill="none" stroke="black" d="M348.969,-37.6641C347.406,-47.625 349.75,-57 356,-57 360.004,-57 362.405,-53.1525 363.202,-47.7682"/>
|
||||
<polygon fill="black" stroke="black" points="366.7,-47.6033 363.031,-37.6641 359.701,-47.7219 366.7,-47.6033"/>
|
||||
<text text-anchor="middle" x="356" y="-60.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 4 -->
|
||||
<g id="node7" class="node"><title>4</title>
|
||||
<ellipse fill="none" stroke="black" cx="438" cy="-21" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="438" y="-17.3" font-family="Times,serif" font-size="14.00">4</text>
|
||||
</g>
|
||||
<!-- 3->4 -->
|
||||
<g id="edge6" class="edge"><title>3->4</title>
|
||||
<path fill="none" stroke="black" d="M374.359,-21C384.703,-21 398.059,-21 409.779,-21"/>
|
||||
<polygon fill="black" stroke="black" points="409.95,-24.5001 419.95,-21 409.95,-17.5001 409.95,-24.5001"/>
|
||||
<text text-anchor="middle" x="397" y="-24.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 4->5 -->
|
||||
<g id="edge7" class="edge"><title>4->5</title>
|
||||
<path fill="none" stroke="black" d="M456.405,-21C466.589,-21 479.751,-21 491.682,-21"/>
|
||||
<polygon fill="black" stroke="black" points="491.744,-24.5001 501.744,-21 491.744,-17.5001 491.744,-24.5001"/>
|
||||
<text text-anchor="middle" x="479" y="-24.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
16
web_src/05_Lectures/00_Computers/unix/images/exp6.dot
Normal file
@@ -0,0 +1,16 @@
|
||||
digraph finite_state_machine {
|
||||
rankdir=LR;
|
||||
{
|
||||
node [style = invis]; I;
|
||||
}
|
||||
node [shape = doublecircle]; 4;
|
||||
node [shape = circle];
|
||||
I -> 0
|
||||
0 -> 1 [ label = "T" ];
|
||||
1 -> 2 [ label = "A" ];
|
||||
1 -> 3 [ label = "G" ];
|
||||
2 -> 4 [ label = "A" ];
|
||||
2 -> 4 [ label = "G" ];
|
||||
3 -> 4 [ label = "A" ];
|
||||
|
||||
}
|
||||
81
web_src/05_Lectures/00_Computers/unix/images/exp6.svg
Normal file
@@ -0,0 +1,81 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!-- Generated by graphviz version 2.36.0 (20140111.2315)
|
||||
-->
|
||||
<!-- Title: finite_state_machine Pages: 1 -->
|
||||
<svg width="390pt" height="98pt"
|
||||
viewBox="0.00 0.00 390.00 98.00" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 94)">
|
||||
<title>finite_state_machine</title>
|
||||
<polygon fill="white" stroke="none" points="-4,4 -4,-94 386,-94 386,4 -4,4"/>
|
||||
<!-- I -->
|
||||
<!-- 0 -->
|
||||
<g id="node3" class="node"><title>0</title>
|
||||
<ellipse fill="none" stroke="black" cx="110" cy="-47" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="110" y="-43.3" font-family="Times,serif" font-size="14.00">0</text>
|
||||
</g>
|
||||
<!-- I->0 -->
|
||||
<g id="edge1" class="edge"><title>I->0</title>
|
||||
<path fill="none" stroke="black" d="M54.0748,-47C62.8864,-47 72.746,-47 81.6534,-47"/>
|
||||
<polygon fill="black" stroke="black" points="81.9117,-50.5001 91.9117,-47 81.9117,-43.5001 81.9117,-50.5001"/>
|
||||
</g>
|
||||
<!-- 4 -->
|
||||
<g id="node2" class="node"><title>4</title>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-56" rx="18" ry="18"/>
|
||||
<ellipse fill="none" stroke="black" cx="360" cy="-56" rx="22" ry="22"/>
|
||||
<text text-anchor="middle" x="360" y="-52.3" font-family="Times,serif" font-size="14.00">4</text>
|
||||
</g>
|
||||
<!-- 1 -->
|
||||
<g id="node4" class="node"><title>1</title>
|
||||
<ellipse fill="none" stroke="black" cx="192" cy="-47" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="192" y="-43.3" font-family="Times,serif" font-size="14.00">1</text>
|
||||
</g>
|
||||
<!-- 0->1 -->
|
||||
<g id="edge2" class="edge"><title>0->1</title>
|
||||
<path fill="none" stroke="black" d="M128.359,-47C138.703,-47 152.059,-47 163.779,-47"/>
|
||||
<polygon fill="black" stroke="black" points="163.95,-50.5001 173.95,-47 163.95,-43.5001 163.95,-50.5001"/>
|
||||
<text text-anchor="middle" x="151" y="-50.8" font-family="Times,serif" font-size="14.00">T</text>
|
||||
</g>
|
||||
<!-- 2 -->
|
||||
<g id="node5" class="node"><title>2</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-72" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-68.3" font-family="Times,serif" font-size="14.00">2</text>
|
||||
</g>
|
||||
<!-- 1->2 -->
|
||||
<g id="edge3" class="edge"><title>1->2</title>
|
||||
<path fill="none" stroke="black" d="M209.576,-52.18C220.374,-55.5544 234.688,-60.0276 246.985,-63.8704"/>
|
||||
<polygon fill="black" stroke="black" points="246.13,-67.27 256.719,-66.9122 248.218,-60.5887 246.13,-67.27"/>
|
||||
<text text-anchor="middle" x="233" y="-63.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 3 -->
|
||||
<g id="node6" class="node"><title>3</title>
|
||||
<ellipse fill="none" stroke="black" cx="274" cy="-18" rx="18" ry="18"/>
|
||||
<text text-anchor="middle" x="274" y="-14.3" font-family="Times,serif" font-size="14.00">3</text>
|
||||
</g>
|
||||
<!-- 1->3 -->
|
||||
<g id="edge4" class="edge"><title>1->3</title>
|
||||
<path fill="none" stroke="black" d="M209.189,-41.1314C220.141,-37.1614 234.837,-31.834 247.365,-27.2926"/>
|
||||
<polygon fill="black" stroke="black" points="248.626,-30.5584 256.835,-23.8599 246.241,-23.9774 248.626,-30.5584"/>
|
||||
<text text-anchor="middle" x="233" y="-37.8" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
<!-- 2->4 -->
|
||||
<g id="edge5" class="edge"><title>2->4</title>
|
||||
<path fill="none" stroke="black" d="M292.247,-73.5545C300.688,-73.9225 310.955,-73.7832 320,-72 323.48,-71.3139 327.041,-70.314 330.526,-69.1438"/>
|
||||
<polygon fill="black" stroke="black" points="331.931,-72.3539 340.022,-65.5139 329.431,-65.8154 331.931,-72.3539"/>
|
||||
<text text-anchor="middle" x="315" y="-76.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
<!-- 2->4 -->
|
||||
<g id="edge6" class="edge"><title>2->4</title>
|
||||
<path fill="none" stroke="black" d="M289.311,-62.1343C295.402,-58.5065 302.763,-54.8378 310,-53 315.679,-51.5579 321.842,-51.1067 327.819,-51.2182"/>
|
||||
<polygon fill="black" stroke="black" points="328.016,-54.74 338.233,-51.9342 328.496,-47.7564 328.016,-54.74"/>
|
||||
<text text-anchor="middle" x="315" y="-56.8" font-family="Times,serif" font-size="14.00">G</text>
|
||||
</g>
|
||||
<!-- 3->4 -->
|
||||
<g id="edge7" class="edge"><title>3->4</title>
|
||||
<path fill="none" stroke="black" d="M291.612,-22.0966C300.267,-24.4962 310.913,-27.8694 320,-32 324.268,-33.94 328.639,-36.2597 332.839,-38.6812"/>
|
||||
<polygon fill="black" stroke="black" points="331.291,-41.836 341.655,-44.0371 334.926,-35.8535 331.291,-41.836"/>
|
||||
<text text-anchor="middle" x="315" y="-35.8" font-family="Times,serif" font-size="14.00">A</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.5 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/filesystem-link.png
Normal file
|
After Width: | Height: | Size: 265 KiB |
|
After Width: | Height: | Size: 198 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/filesystem.png
Normal file
|
After Width: | Height: | Size: 231 KiB |
480
web_src/05_Lectures/00_Computers/unix/images/loop.svg
Normal file
@@ -0,0 +1,480 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="130.4149mm"
|
||||
height="51.971745mm"
|
||||
viewBox="0 0 462.10005 184.15186"
|
||||
id="svg2"
|
||||
version="1.1"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="loop.svg">
|
||||
<defs
|
||||
id="defs4">
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker4676"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path4678"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker4654"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow1Lend">
|
||||
<path
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
id="path4656"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path4375"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 0,0 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1pt;stroke-opacity:1"
|
||||
transform="matrix(-0.8,0,0,-0.8,-10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
r="2.51"
|
||||
gradientTransform="matrix(0.41910289,0,0,0.42014875,414.6879,174.50255)"
|
||||
cx="37.496"
|
||||
cy="39.51"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
id="radialGradient3091">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop6449" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#777973;stop-opacity:0"
|
||||
id="stop6451" />
|
||||
</radialGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="40.253"
|
||||
y1="42.319"
|
||||
gradientTransform="matrix(0.41910289,0,0,0.42411604,414.6879,174.34637)"
|
||||
x2="36.452"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="38"
|
||||
id="linearGradient3093">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a9aaa7"
|
||||
id="stop2216" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#676964"
|
||||
id="stop2218" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.492"
|
||||
y1="1.6538"
|
||||
gradientTransform="matrix(0.5307098,0,0,0.43010531,413.33993,171.1056)"
|
||||
x2="17.199"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="26.729"
|
||||
id="linearGradient3097">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2669" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#fcfcff;stop-opacity:.23894"
|
||||
id="stop2671" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="20.339"
|
||||
y1="19.637"
|
||||
gradientTransform="matrix(0.45908253,0,0,0.52969881,413.00212,169.39388)"
|
||||
x2="48.845"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="49.731"
|
||||
id="linearGradient3100">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#ffffff"
|
||||
id="stop2240" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#ffffff;stop-opacity:0"
|
||||
id="stop2242" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="11.048"
|
||||
y1="9.1463"
|
||||
gradientTransform="matrix(0.48241909,0,0,0.61177071,412.51349,167.70698)"
|
||||
x2="26.178"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="30.343"
|
||||
id="linearGradient3115">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#616161"
|
||||
id="stop4256" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#a0a0a0"
|
||||
id="stop4258" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="29.87"
|
||||
y1="32.286"
|
||||
gradientTransform="matrix(0.46367733,0,0,0.53213914,412.94139,168.79614)"
|
||||
x2="24.842"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="14.158"
|
||||
id="linearGradient3119">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#777973"
|
||||
id="stop2208" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#cbccca"
|
||||
id="stop2210" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
x1="8.6529"
|
||||
y1="9.5865"
|
||||
gradientTransform="matrix(0.46367733,0,0,0.53213914,412.94139,168.79614)"
|
||||
x2="21.305"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
y2="32.498"
|
||||
id="linearGradient3121">
|
||||
<stop
|
||||
offset="0"
|
||||
style="stop-color:#a2a59c"
|
||||
id="stop5178" />
|
||||
<stop
|
||||
offset="1"
|
||||
style="stop-color:#535750"
|
||||
id="stop5180" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="1.4"
|
||||
inkscape:cx="365.2324"
|
||||
inkscape:cy="110.99897"
|
||||
inkscape:document-units="px"
|
||||
inkscape:current-layer="layer1"
|
||||
showgrid="false"
|
||||
fit-margin-top="10"
|
||||
fit-margin-left="10"
|
||||
fit-margin-right="10"
|
||||
fit-margin-bottom="10"
|
||||
inkscape:window-width="1857"
|
||||
inkscape:window-height="1056"
|
||||
inkscape:window-x="63"
|
||||
inkscape:window-y="24"
|
||||
inkscape:window-maximized="1" />
|
||||
<metadata
|
||||
id="metadata7">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-2.0214022,-511.28627)">
|
||||
<g
|
||||
id="g4196"
|
||||
transform="translate(0,1.0714569)">
|
||||
<rect
|
||||
y="546.64789"
|
||||
x="64.911835"
|
||||
height="75"
|
||||
width="155.71428"
|
||||
id="rect4136"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4138"
|
||||
y="588.56195"
|
||||
x="118.26897"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="588.56195"
|
||||
x="118.26897"
|
||||
id="tspan4140"
|
||||
sodipodi:role="line">User input</tspan></text>
|
||||
</g>
|
||||
<flowRoot
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
id="flowRoot4225-8"
|
||||
xml:space="preserve"
|
||||
transform="translate(381.51674,-1.0713978)"><flowRegion
|
||||
id="flowRegion4227-8"><rect
|
||||
y="535.21936"
|
||||
x="29.285715"
|
||||
height="112.85714"
|
||||
width="197.85715"
|
||||
id="rect4229-8" /></flowRegion><flowPara
|
||||
id="flowPara4231-6" /></flowRoot> <g
|
||||
transform="translate(185.7581,1.0714568)"
|
||||
id="g4196-1">
|
||||
<rect
|
||||
y="546.64789"
|
||||
x="64.911835"
|
||||
height="75"
|
||||
width="155.71428"
|
||||
id="rect4136-4"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:2;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
id="text4138-6"
|
||||
y="568.56195"
|
||||
x="111.55468"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:16px;line-height:125%;font-family:Sans;-inkscape-font-specification:'Sans, Normal';text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
y="568.56195"
|
||||
x="114.10155"
|
||||
id="tspan4140-9"
|
||||
sodipodi:role="line">Interpret </tspan><tspan
|
||||
id="tspan4174"
|
||||
y="588.56195"
|
||||
x="111.55468"
|
||||
sodipodi:role="line">&</tspan><tspan
|
||||
id="tspan4176"
|
||||
y="608.56195"
|
||||
x="111.55468"
|
||||
sodipodi:role="line">Render</tspan></text>
|
||||
<flowRoot
|
||||
xml:space="preserve"
|
||||
id="flowRoot4225"
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"><flowRegion
|
||||
id="flowRegion4227"><rect
|
||||
id="rect4229"
|
||||
width="197.85715"
|
||||
height="112.85714"
|
||||
x="29.285715"
|
||||
y="535.21936" /></flowRegion><flowPara
|
||||
id="flowPara4231" /></flowRoot> </g>
|
||||
<g
|
||||
transform="matrix(1.122807,0,0,1.122807,98.197502,-194.17476)"
|
||||
id="g4316-8">
|
||||
<circle
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:1.78125;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="path4288-3"
|
||||
cx="244.64285"
|
||||
cy="694.14789"
|
||||
r="20.357143" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1.78125;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
d="m 244.28571,677.3622 0,19.28572 8.21429,-8.21429"
|
||||
id="path4290-8"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#marker4676)"
|
||||
d="m 220.62611,585.21935 30.04383,0"
|
||||
id="path4358"
|
||||
inkscape:connector-type="polyline"
|
||||
inkscape:connector-curvature="0"
|
||||
inkscape:connection-start="#g4196" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.99999994px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow1Lend)"
|
||||
d="m 405.91582,584.50506 22.27256,0 0,75 -390.233907,0 0,-75 25.056636,0"
|
||||
id="path4366"
|
||||
inkscape:connector-curvature="0" />
|
||||
<g
|
||||
transform="matrix(1.4342301,0,0,1.4342301,162.37955,545.01931)"
|
||||
inkscape:label="Layer 1"
|
||||
id="layer1-6">
|
||||
<rect
|
||||
x="4.4926"
|
||||
y="12.402"
|
||||
width="31.254"
|
||||
height="31.254"
|
||||
ry="2.7110016"
|
||||
rx="2.3496926"
|
||||
style="fill:url(#linearGradient3119);fill-rule:evenodd;stroke:url(#linearGradient3121);stroke-width:0.5202024;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1316" />
|
||||
<rect
|
||||
x="7.2855"
|
||||
y="14.71"
|
||||
width="25.723"
|
||||
height="25.723"
|
||||
ry="1.0167127"
|
||||
rx="0.79561847"
|
||||
style="fill:#999999;fill-rule:evenodd;stroke:url(#linearGradient3115);stroke-width:0.54391551;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1314" />
|
||||
<path
|
||||
d="m 9.1725,18.812 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path1345" />
|
||||
<path
|
||||
d="m 9.1725,20.415 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2264" />
|
||||
<path
|
||||
d="m 9.1725,22.018 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2266" />
|
||||
<path
|
||||
d="m 9.1725,23.621 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2268" />
|
||||
<path
|
||||
d="m 9.1725,25.224 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2270" />
|
||||
<path
|
||||
d="m 9.1725,26.826 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2272" />
|
||||
<path
|
||||
d="m 9.1725,28.429 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2274" />
|
||||
<path
|
||||
d="m 9.1725,30.032 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2276" />
|
||||
<path
|
||||
d="m 9.1725,31.635 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2278" />
|
||||
<path
|
||||
d="m 9.1725,33.238 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2280" />
|
||||
<path
|
||||
d="m 9.1725,34.841 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2282" />
|
||||
<path
|
||||
d="m 9.1725,36.443 21.981,0"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.2556801;fill:#333333;stroke:#000000;stroke-width:0.5178597"
|
||||
id="path2284" />
|
||||
<rect
|
||||
x="5.2220001"
|
||||
y="13.201"
|
||||
width="29.655001"
|
||||
height="29.655001"
|
||||
ry="2.1185584"
|
||||
rx="1.8252301"
|
||||
style="opacity:0.76374003;fill:none;stroke:url(#linearGradient3100);stroke-width:0.5187034;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect2232" />
|
||||
<path
|
||||
d="m 10.092,16.573 c -0.32221,0 -0.9691,0.13093 -0.9691,0.70632 l 0.072686,11.371 c 10.881,-0.663 8.6974,-5.683 22.062,-8.198 l 0.1031,-3.4138 c -0.04819,-0.77456 -0.47381,-0.42343 -1.1332,-0.41888 z"
|
||||
inkscape:connector-curvature="0"
|
||||
style="opacity:0.92194998;fill:url(#linearGradient3097);fill-rule:evenodd"
|
||||
sodipodi:nodetypes="ccccccc"
|
||||
id="path2443" />
|
||||
<rect
|
||||
x="8.4154997"
|
||||
y="15.88"
|
||||
width="23.545"
|
||||
height="23.545"
|
||||
ry="0.074172191"
|
||||
rx="0.056801904"
|
||||
style="opacity:0.71429001;fill:#333333;stroke:#000000;stroke-width:1.10268223;stroke-linecap:round;stroke-linejoin:round"
|
||||
id="rect1340" />
|
||||
<rect
|
||||
x="27.993999"
|
||||
y="40.487"
|
||||
width="2.4164"
|
||||
height="2.4168"
|
||||
ry="0.31902829"
|
||||
rx="0.15012236"
|
||||
style="fill:url(#radialGradient3091);fill-rule:evenodd;stroke:url(#linearGradient3093);stroke-width:0.48853388;stroke-linecap:round"
|
||||
id="rect5025" />
|
||||
<rect
|
||||
x="28.51"
|
||||
y="40.948002"
|
||||
width="1.3896"
|
||||
height="1.3896"
|
||||
ry="0.27139297"
|
||||
rx="0.27139297"
|
||||
style="fill:#93d94c;fill-rule:evenodd"
|
||||
id="rect6458" />
|
||||
<circle
|
||||
transform="matrix(0.60373,0,0,0.60835,11.884,17.799)"
|
||||
style="color:#000000;fill:#ffffff"
|
||||
id="path2300"
|
||||
cx="28.3125"
|
||||
cy="38.75"
|
||||
r="0.5625" />
|
||||
<g
|
||||
transform="scale(1.0006,0.99939)"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.22346482"
|
||||
id="text3174">
|
||||
<path
|
||||
d="m 10.967,31.315 c -0.1984,-0.19732 -0.29987,-0.43784 -0.3044,-0.72156 -0.0045,-0.2837 0.09386,-0.52155 0.29519,-0.71355 0.20213,-0.2024 0.44873,-0.3036 0.73978,-0.3036 0.28972,7e-6 0.54686,0.14273 0.77142,0.42817 l 2.3808,2.2526 0,0.0076 c 0.08197,0.07477 0.14485,0.1727 0.18865,0.29379 0.04379,0.1211 0.07102,0.25828 0.08171,0.41155 -6e-6,0.25875 -0.10401,0.49212 -0.31202,0.70013 l -2.3547,2.3804 c -0.19573,0.19573 -0.43912,0.29359 -0.73017,0.29359 -0.29212,1e-6 -0.53665,-0.0984 -0.73358,-0.29519 -0.19693,-0.19679 -0.29539,-0.43711 -0.29539,-0.72096 -1e-6,-0.28251 0.13952,-0.53538 0.41856,-0.75861 l 1.5633,-1.6198 z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.22346482"
|
||||
id="path3124"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
d="m 17.439,35.534 c -0.25688,2e-6 -0.4733,0.08799 -0.64926,0.26395 -0.17597,0.17597 -0.26395,0.38798 -0.26395,0.63604 -1e-6,0.2494 0.08765,0.46181 0.26295,0.63725 0.1753,0.17543 0.39205,0.26315 0.65026,0.26315 l 7.4635,0 c 0.2566,0 0.47295,-0.08805 0.64906,-0.26415 0.17609,-0.1761 0.26414,-0.38818 0.26415,-0.63625 -10e-6,-0.24673 -0.08839,-0.45841 -0.26515,-0.63504 C 25.37378,35.62232 25.15776,35.534 24.9025,35.534 Z"
|
||||
style="fill:#ffffff;stroke:#b3b3b3;stroke-width:0.22346482"
|
||||
id="path3126"
|
||||
inkscape:connector-curvature="0" />
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 18 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/nano.png
Normal file
|
After Width: | Height: | Size: 32 KiB |
@@ -0,0 +1,135 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
version="1.1"
|
||||
width="487.70905"
|
||||
height="344.35294"
|
||||
id="svg3015"
|
||||
inkscape:version="0.91 r13725"
|
||||
sodipodi:docname="command.svg">
|
||||
<sodipodi:namedview
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1"
|
||||
objecttolerance="10"
|
||||
gridtolerance="10"
|
||||
guidetolerance="10"
|
||||
inkscape:pageopacity="0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:window-width="1839"
|
||||
inkscape:window-height="1050"
|
||||
id="namedview16"
|
||||
showgrid="false"
|
||||
showguides="true"
|
||||
inkscape:guide-bbox="true"
|
||||
fit-margin-top="5"
|
||||
fit-margin-left="5"
|
||||
fit-margin-right="5"
|
||||
fit-margin-bottom="5"
|
||||
inkscape:zoom="1.4475853"
|
||||
inkscape:cx="558.29851"
|
||||
inkscape:cy="246.76436"
|
||||
inkscape:window-x="81"
|
||||
inkscape:window-y="30"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:current-layer="svg3015" />
|
||||
<defs
|
||||
id="defs3017" />
|
||||
<metadata
|
||||
id="metadata3020">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text3793"
|
||||
y="169.75429"
|
||||
x="182.19489"><tspan
|
||||
style="font-size:32px"
|
||||
id="tspan3795"
|
||||
y="169.75429"
|
||||
x="182.19489">OBITools</tspan></text>
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
y="193.93248"
|
||||
x="170.65582"
|
||||
id="text38334"><tspan
|
||||
style="font-size:32px"
|
||||
y="193.93248"
|
||||
x="170.65582"
|
||||
id="tspan38336">command</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
style="fill:none;stroke:#000000;stroke-width:1;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path3830"
|
||||
d="m 81.459988,119.50094 0,10.59375 -37.8125,0 0,20 37.8125,0 0,9.1875 34.406252,-19.875 -34.406252,-19.90625 z" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text3837"
|
||||
y="118.01492"
|
||||
x="3.546875"><tspan
|
||||
id="tspan3839"
|
||||
y="118.01492"
|
||||
x="3.546875">parameters</tspan></text>
|
||||
<path
|
||||
id="path3029-8"
|
||||
style="fill:none;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
d="m 334.42861,281.2057 24.30925,-0.0113 0,25.5 64.625,-37.28125 -64.625,-37.3125 0,25.5 -24.30925,-0.0679 c 0,0 -17.5031,0.78696 -15.54079,-33.01333 l 84.0162,-0.3399 0,-108.71875 -140.0625,0 0,-44.843757 25.5,-44.15625 -74.59375,0 25.5,44.1875 0,44.812507 -140.062502,0 0,9.4375 25.125002,14.5 -25.125002,14.5 0,70.28125 140.062502,0 0,24.375 -25.5,0 37.28125,64.625 37.3125,-64.625 -25.5,0 0,-24.375 33.03326,0.15674 c -0.4583,59.01777 38.55383,56.86944 38.55383,56.86944 z"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccccccccccccccccccccccccccccc" />
|
||||
<text
|
||||
sodipodi:linespacing="125%"
|
||||
style="font-style:normal;font-weight:normal;font-size:16px;line-height:125%;font-family:Sans;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none"
|
||||
xml:space="preserve"
|
||||
id="text3826-6"
|
||||
y="274.341"
|
||||
x="435.19342"><tspan
|
||||
id="tspan3828-4"
|
||||
y="274.341"
|
||||
x="435.19342">stderr</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="153.0134"
|
||||
y="16.396484"
|
||||
id="text38338"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan38340"
|
||||
x="153.0134"
|
||||
y="16.396484"
|
||||
style="font-size:15px">decorated fasta sequence</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:40px;line-height:125%;font-family:sans-serif;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="153.0134"
|
||||
y="336.23282"
|
||||
id="text38338-1"
|
||||
sodipodi:linespacing="125%"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan38340-8"
|
||||
x="153.0134"
|
||||
y="336.23282"
|
||||
style="font-size:15px">decorated fasta sequence</tspan></text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.3 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/obitools.png
Normal file
|
After Width: | Height: | Size: 86 KiB |
BIN
web_src/05_Lectures/00_Computers/unix/images/permissions.png
Normal file
|
After Width: | Height: | Size: 13 KiB |
96
web_src/05_Lectures/00_Computers/unix/images/terminal.svg
Normal file
@@ -0,0 +1,96 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
<svg xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:svg="http://www.w3.org/2000/svg" xmlns:ns1="http://sozi.baierouge.fr" id="svg1306" sodipodi:docname="terminal_square.svg" inkscape:export-filename="/home/andreas/projekt/bild/tango/terminal4.png" viewBox="0 0 32 32" sodipodi:version="0.32" inkscape:export-xdpi="240.00000" version="1.1" inkscape:output_extension="org.inkscape.output.svg.inkscape" inkscape:export-ydpi="240.00000" inkscape:version="0.48.0 r9654">
|
||||
<defs id="defs1308">
|
||||
<radialGradient id="radialGradient3091" gradientUnits="userSpaceOnUse" cy="39.51" cx="37.496" gradientTransform="matrix(.60109 0 0 .60259 6.6642 17.887)" r="2.51" inkscape:collect="always">
|
||||
<stop id="stop6449" style="stop-color:#777973" offset="0"/>
|
||||
<stop id="stop6451" style="stop-color:#777973;stop-opacity:0" offset="1"/>
|
||||
</radialGradient>
|
||||
<linearGradient id="linearGradient3093" y2="38" gradientUnits="userSpaceOnUse" x2="36.452" gradientTransform="matrix(.60109 0 0 .60828 6.6642 17.663)" y1="42.319" x1="40.253" inkscape:collect="always">
|
||||
<stop id="stop2216" style="stop-color:#a9aaa7" offset="0"/>
|
||||
<stop id="stop2218" style="stop-color:#676964" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3097" y2="26.729" gradientUnits="userSpaceOnUse" x2="17.199" gradientTransform="matrix(.76116 0 0 .61687 4.7309 13.015)" y1="1.6538" x1="11.492" inkscape:collect="always">
|
||||
<stop id="stop2669" style="stop-color:#ffffff" offset="0"/>
|
||||
<stop id="stop2671" style="stop-color:#fcfcff;stop-opacity:.23894" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3100" y2="49.731" gradientUnits="userSpaceOnUse" x2="48.845" gradientTransform="matrix(.65843 0 0 .75971 4.2464 10.56)" y1="19.637" x1="20.339" inkscape:collect="always">
|
||||
<stop id="stop2240" style="stop-color:#ffffff" offset="0"/>
|
||||
<stop id="stop2242" style="stop-color:#ffffff;stop-opacity:0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3115" y2="30.343" gradientUnits="userSpaceOnUse" x2="26.178" gradientTransform="matrix(.69190 0 0 .87742 3.5456 8.1406)" y1="9.1463" x1="11.048" inkscape:collect="always">
|
||||
<stop id="stop4256" style="stop-color:#616161" offset="0"/>
|
||||
<stop id="stop4258" style="stop-color:#a0a0a0" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3119" y2="14.158" gradientUnits="userSpaceOnUse" x2="24.842" gradientTransform="matrix(.66502 0 0 .76321 4.1593 9.7027)" y1="32.286" x1="29.87" inkscape:collect="always">
|
||||
<stop id="stop2208" style="stop-color:#777973" offset="0"/>
|
||||
<stop id="stop2210" style="stop-color:#cbccca" offset="1"/>
|
||||
</linearGradient>
|
||||
<linearGradient id="linearGradient3121" y2="32.498" gradientUnits="userSpaceOnUse" x2="21.305" gradientTransform="matrix(.66502 0 0 .76321 4.1593 9.7027)" y1="9.5865" x1="8.6529" inkscape:collect="always">
|
||||
<stop id="stop5178" style="stop-color:#a2a59c" offset="0"/>
|
||||
<stop id="stop5180" style="stop-color:#535750" offset="1"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<sodipodi:namedview id="base" fit-margin-left="0" inkscape:showpageshadow="false" inkscape:zoom="4" borderopacity="0.19607843" inkscape:current-layer="layer1" inkscape:cx="-25.016101" inkscape:cy="70.017551" inkscape:grid-bbox="true" inkscape:window-maximized="1" showgrid="false" fit-margin-right="0" inkscape:guide-bbox="true" showguides="true" bordercolor="#666666" inkscape:window-x="-4" inkscape:window-y="-4" fit-margin-bottom="0" inkscape:window-width="1280" inkscape:pageopacity="0.0" inkscape:pageshadow="2" pagecolor="#ffffff" inkscape:document-units="px" inkscape:window-height="981" fit-margin-top="0"/>
|
||||
<g id="layer1" inkscape:label="Layer 1" inkscape:groupmode="layer" transform="translate(-4.1195 -12.029)">
|
||||
<rect id="rect1316" style="stroke-linejoin:round;fill-rule:evenodd;stroke:url(#linearGradient3121);stroke-linecap:round;stroke-width:.74609;fill:url(#linearGradient3119)" rx="3.37" ry="3.8882" height="31.254" width="31.254" y="12.402" x="4.4926"/>
|
||||
<rect id="rect1314" style="stroke-linejoin:round;fill-rule:evenodd;stroke:url(#linearGradient3115);stroke-linecap:round;stroke-width:.78010;fill:#999999" rx="1.1411" ry="1.4582" height="25.723" width="25.723" y="14.71" x="7.2855"/>
|
||||
<path id="path1345" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 18.812h21.981"/>
|
||||
<path id="path2264" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 20.415h21.981"/>
|
||||
<path id="path2266" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 22.018h21.981"/>
|
||||
<path id="path2268" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 23.621h21.981"/>
|
||||
<path id="path2270" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 25.224h21.981"/>
|
||||
<path id="path2272" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 26.826h21.981"/>
|
||||
<path id="path2274" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 28.429h21.981"/>
|
||||
<path id="path2276" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 30.032h21.981"/>
|
||||
<path id="path2278" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 31.635h21.981"/>
|
||||
<path id="path2280" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 33.238h21.981"/>
|
||||
<path id="path2282" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 34.841h21.981"/>
|
||||
<path id="path2284" style="opacity:.25568;stroke:#000000;stroke-width:.74273;fill:#333333" inkscape:connector-curvature="0" d="m9.1725 36.443h21.981"/>
|
||||
<rect id="rect2232" style="opacity:.76374;stroke-linejoin:round;stroke:url(#linearGradient3100);stroke-linecap:round;stroke-width:.74394;fill:none" rx="2.6178" ry="3.0385" height="29.655" width="29.655" y="13.201" x="5.222"/>
|
||||
<path id="path2443" sodipodi:nodetypes="ccccccc" style="opacity:.92195;fill-rule:evenodd;fill:url(#linearGradient3097)" inkscape:connector-curvature="0" d="m10.092 16.573c-0.32221 0-0.9691 0.13093-0.9691 0.70632l0.072686 11.371c10.881-0.663 8.6974-5.683 22.062-8.198l0.1031-3.4138c-0.04819-0.77456-0.47381-0.42343-1.1332-0.41888z"/>
|
||||
<rect id="rect1340" style="opacity:.71429;stroke-linejoin:round;stroke:#000000;stroke-linecap:round;stroke-width:1.5815;fill:#333333" rx=".081467" ry=".10638" height="23.545" width="23.545" y="15.88" x="8.4155"/>
|
||||
<rect id="rect5025" style="fill-rule:evenodd;stroke:url(#linearGradient3093);stroke-linecap:round;stroke-width:.70067;fill:url(#radialGradient3091)" rx=".21531" ry=".45756" height="2.4168" width="2.4164" y="40.487" x="27.994"/>
|
||||
<rect id="rect6458" style="fill-rule:evenodd;fill:#93d94c" rx=".38924" ry=".38924" height="1.3896" width="1.3896" y="40.948" x="28.51"/>
|
||||
<path id="path2300" sodipodi:rx="0.5625" sodipodi:ry="0.5625" style="color:#000000;fill:#ffffff" sodipodi:type="arc" d="m28.875 38.75a0.5625 0.5625 0 1 1 -1.125 0 0.5625 0.5625 0 1 1 1.125 0z" transform="matrix(.60373 0 0 .60835 11.884 17.799)" sodipodi:cy="38.75" sodipodi:cx="28.3125"/>
|
||||
<g id="text3174" style="stroke:#b3b3b3;stroke-width:.32050;fill:#ffffff" transform="scale(1.0006 .99939)">
|
||||
<path id="path3124" style="stroke:#b3b3b3;fill:#ffffff" d="m10.967 31.315c-0.1984-0.19732-0.29987-0.43784-0.3044-0.72156-0.0045-0.2837 0.09386-0.52155 0.29519-0.71355 0.20213-0.2024 0.44873-0.3036 0.73978-0.3036 0.28972 0.000007 0.54686 0.14273 0.77142 0.42817l2.3808 2.2526v0.0076c0.08197 0.07477 0.14485 0.1727 0.18865 0.29379 0.04379 0.1211 0.07102 0.25828 0.08171 0.41155-0.000006 0.25875-0.10401 0.49212-0.31202 0.70013l-2.3547 2.3804c-0.19573 0.19573-0.43912 0.29359-0.73017 0.29359-0.29212 0.000001-0.53665-0.0984-0.73358-0.29519s-0.29539-0.43711-0.29539-0.72096c-0.000001-0.28251 0.13952-0.53538 0.41856-0.75861l1.5633-1.6198z"/>
|
||||
<path id="path3126" style="stroke:#b3b3b3;fill:#ffffff" d="m17.439 35.534c-0.25688 0.000002-0.4733 0.08799-0.64926 0.26395-0.17597 0.17597-0.26395 0.38798-0.26395 0.63604-0.000001 0.2494 0.08765 0.46181 0.26295 0.63725 0.1753 0.17543 0.39205 0.26315 0.65026 0.26315h7.4635c0.2566 0 0.47295-0.08805 0.64906-0.26415 0.17609-0.1761 0.26414-0.38818 0.26415-0.63625-0.00001-0.24673-0.08839-0.45841-0.26515-0.63504-0.17678-0.17663-0.3928-0.26495-0.64806-0.26495z"/>
|
||||
</g>
|
||||
</g>
|
||||
<metadata>
|
||||
<rdf:RDF>
|
||||
<cc:Work>
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
|
||||
<cc:license rdf:resource="http://creativecommons.org/licenses/publicdomain/"/>
|
||||
<dc:publisher>
|
||||
<cc:Agent rdf:about="http://openclipart.org/">
|
||||
<dc:title>Openclipart</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:publisher>
|
||||
<dc:title>Terminal Icon 1:1 ratio</dc:title>
|
||||
<dc:date>2011-01-27T11:10:57</dc:date>
|
||||
<dc:description>based on tango utilities terminal by warszawianka, made for alternativeto.net</dc:description>
|
||||
<dc:source>https://openclipart.org/detail/110197/terminal-icon-1:1-ratio-by-n2j3</dc:source>
|
||||
<dc:creator>
|
||||
<cc:Agent>
|
||||
<dc:title>n2j3</dc:title>
|
||||
</cc:Agent>
|
||||
</dc:creator>
|
||||
<dc:subject>
|
||||
<rdf:Bag>
|
||||
<rdf:li>cli</rdf:li>
|
||||
<rdf:li>square</rdf:li>
|
||||
<rdf:li>terminal</rdf:li>
|
||||
</rdf:Bag>
|
||||
</dc:subject>
|
||||
</cc:Work>
|
||||
<cc:License rdf:about="http://creativecommons.org/licenses/publicdomain/">
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Reproduction"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#Distribution"/>
|
||||
<cc:permits rdf:resource="http://creativecommons.org/ns#DerivativeWorks"/>
|
||||
</cc:License>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 10 KiB |
295
web_src/05_Lectures/00_Computers/unix/slides.qmd
Normal file
@@ -0,0 +1,295 @@
|
||||
|
||||
---
|
||||
title: |
|
||||
DNA metabarcoding School
|
||||
Unix Basics
|
||||
author: frederic.boyer@univ-grenoble-alpes.fr
|
||||
format:
|
||||
revealjs:
|
||||
css: ../../slides.css
|
||||
transition: slide
|
||||
scrollable: true
|
||||
theme: beige
|
||||
html-math-method: mathjax
|
||||
---
|
||||
|
||||
# Introduction to Unix
|
||||
|
||||
|
||||
## Interacting with a UNIX computer
|
||||
|
||||
|
||||
### The command shell endless loop
|
||||
|
||||
{ width=80% }
|
||||
|
||||
|
||||
|
||||
## Bash
|
||||
|
||||
The basic command interpreter on the machine (and most often found on a linux machine) is `bash`.
|
||||
|
||||
|
||||
> Bash is a command processor that typically runs in a text window, where the user types commands that cause actions. Bash can also read commands from a file, called a script. Like all Unix shells, it supports filename globbing (wildcard matching), piping, here documents, command substitution, variables and control structures for condition-testing and iteration. The keywords, syntax and other basic features of the language were all copied from sh. Other features, e.g., history, were copied from csh and ksh. Bash is a POSIX shell, but with a number of extensions.
|
||||
>
|
||||
> [wikipedia:bash](https://en.wikipedia.org/wiki/Bash_%28Unix_shell%29)
|
||||
|
||||
|
||||
## RTFM !
|
||||
|
||||
> RTFM is an initialism for the expression "read the fucking manual" or, in the context of the Unix computer operating system, "read the fucking man page". The RTFM comment is usually expressed when the speaker is irritated by another person's question or lack of knowledge. It refers to either that person's inability to read a technical manual, or to their perceived laziness in not doing so first, before asking the question.
|
||||
>
|
||||
> [wikipedia:RTFM](https://en.wikipedia.org/wiki/RTFM)
|
||||
|
||||
|
||||
The official `bash` documentation: [documentation]( https://www.gnu.org/software/bash/manual/ )
|
||||
|
||||
|
||||
## RTFM: getting help with `man`
|
||||
|
||||
> A man page (short for manual page) is a form of software documentation usually found on a Unix or Unix-like operating system. Topics covered include computer programs (including library and system calls), formal standards and conventions, and even abstract concepts. A user may invoke a man page by issuing the man command.
|
||||
>
|
||||
> [wikipedia:man page](https://en.wikipedia.org/wiki/Man_page)
|
||||
|
||||
| Useful command | What it does |
|
||||
|----------------------|-----------------------------------------|
|
||||
| `man <command>` | prints manual for the `command` command |
|
||||
|
||||
For example, to get the manual page for the `man` command:
|
||||
|
||||
```bash
|
||||
man man
|
||||
```
|
||||
|
||||
## RTFM: getting help with `-h` or `--help`
|
||||
|
||||
When there is no man page associated to a command one can use the `-h` or `--help` options:
|
||||
|
||||
For example, to get the help associated to the `man` command:
|
||||
|
||||
```bash
|
||||
man --help
|
||||
```
|
||||
|
||||
# Filesystem -- basic commands and streams
|
||||
|
||||
{ width=40% }
|
||||
|
||||
## Absolute path
|
||||
|
||||
> An absolute or full path points to the same location in a file system, regardless of the current working directory. To do that, it must include the root directory.
|
||||
>
|
||||
> [wikipedia:Path(computing)](https://en.wikipedia.org/wiki/Path_(computing))
|
||||
|
||||
The root of the filesystem is designed by `/`.
|
||||
|
||||
The different part of the path are separated by `/`.
|
||||
|
||||
## Absolute path
|
||||
|
||||
|
||||
{ width=30% }
|
||||
|
||||
The red path is : `/etc/passwd`
|
||||
|
||||
## Relative path
|
||||
|
||||
> By contrast, a relative path starts from some given working directory, avoiding the need to provide the full absolute path.
|
||||
>
|
||||
> [wikipedia:Path (computing)]( https://en.wikipedia.org/wiki/Path_(computing) )
|
||||
|
||||
## Special directories :
|
||||
- `~` : *home directory* for the current user
|
||||
- `~name` : *home directory* for user *name*
|
||||
- `.` : Current directory
|
||||
- `..` : Parent directory
|
||||
|
||||
{ width=30% }
|
||||
|
||||
|
||||
## Useful commands to interact with the filesystem
|
||||
|
||||
| Useful commands | What it does |
|
||||
|----------------------------|-----------------------------|
|
||||
| `pwd` | print working directory |
|
||||
| `cd <directory>` | change directory |
|
||||
| `mkdir <filename>` | create directory |
|
||||
| `ls <filename>` | list files and directories |
|
||||
| `touch <filename>` | create or touch a file |
|
||||
| `cp <filename> <filename>` | copy files or directories |
|
||||
| `mv <filename> <filename>` | move files or directories |
|
||||
| `rm <filename>` | remove files or directories |
|
||||
|
||||
|
||||
## Permissions
|
||||
|
||||
Files and directories are assigned permissions or access rights to specific users and groups of users. The permissions control the ability of the users to view, change, navigate, and execute the contents of the file system.
|
||||
|
||||
> Permissions on Unix-like systems are managed in three distinct scopes or classes.
|
||||
> These scopes are known as user, group, and others.
|
||||
>
|
||||
> [wikipedia: unix permissions](https://en.wikipedia.org/wiki/File_system_permissions#Traditional_Unix_permissions)
|
||||
|
||||
## Permissions
|
||||
|
||||
{ width=10% }
|
||||
|
||||
> The modes indicate which permissions are to be granted or taken away from the specified classes.
|
||||
> There are three basic modes which correspond to the basic permissions:
|
||||
>
|
||||
> | Mode | Name | Description |
|
||||
> |------|---------|--------------------------------------------|
|
||||
> | r | read | read a file or list a directory's contents |
|
||||
> | w | write | write to a file or directory |
|
||||
> | x | execute | execute a file or recurse a directory tree |
|
||||
>
|
||||
> [wikipedia:modes](https://en.wikipedia.org/wiki/Modes_(Unix))
|
||||
|
||||
## View and change permissions
|
||||
|
||||
| Useful commands | What it does |
|
||||
|------------------------------|--------------------|
|
||||
| `ls -l` | view permissions |
|
||||
| `chmod <options> <filename>` | change permissions |
|
||||
|
||||
|
||||
## For example:
|
||||
|
||||
```bash
|
||||
fboyer@obitools:~/$ ls -l index.html
|
||||
-rw-rw-r-- 1 fboyer fboyer 3101 déc. 21 17:09 index.html
|
||||
fboyer@obitools:~/$ chmod 500 index.html
|
||||
fboyer@obitools:~/$ ls -l index.html
|
||||
-r-x------ 1 fboyer fboyer 3101 déc. 21 17:09 index.html
|
||||
```
|
||||
|
||||
|
||||
|
||||
# Commands to work with text
|
||||
|
||||
## Visualize the content of a file
|
||||
|
||||
| Useful commands | What it does |
|
||||
|--------------------|----------------------------------------|
|
||||
| `less <filename>` | utility to explore text files |
|
||||
|
||||
|
||||
## The `less` command
|
||||
|
||||
| shortcut | What it does |
|
||||
|-----------------------|-------------------------------------------|
|
||||
| `h` | display help |
|
||||
| `q` | quit |
|
||||
| `/` | search for a regular pattern |
|
||||
| `n` | for the Next occurence of the pattern |
|
||||
| `shift-n` | for the previous occurence of the pattern |
|
||||
| `arrows` and `space` | to navigate |
|
||||
| `g` and `G` | go to top and end of the file |
|
||||
|
||||
## Edit a text file
|
||||
|
||||
| Useful commands | What it does |
|
||||
|--------------------|--------------------|
|
||||
| `nano <filename>` | Simple text editor |
|
||||
|
||||
|
||||
{ width=100% }
|
||||
|
||||
## Basic `Unix` commands to manipulate text files
|
||||
|
||||
| Useful commands | What it does |
|
||||
|-------------------------------|------------------------------------------------------------------|
|
||||
| `cat <filename>` | output the content of `filename` file |
|
||||
| `head [-<N>] <filename>` | output the first `N` lines of `filename` |
|
||||
| `tail [-<N>] <filename>` | output the last `N` lines of `filename` |
|
||||
| `sort [options] <filename>` | sort the content of `filename` and output it |
|
||||
| `cut [options] <filename>` | extract some column from `filename` and output it |
|
||||
| `diff [options] <filenames>` | compare files line by line and output the differences |
|
||||
|
||||
## Basic `Unix` commands to manipulate text files
|
||||
|
||||
| Useful commands | What it does |
|
||||
|-------------------------------|------------------------------------------------------------------|
|
||||
| `join [options] <filename> <filename>` | join files on the basis of column content |
|
||||
| `paste [options] <filenames>` | paste files line by line |
|
||||
| `wc [options] <filenames>` | count characters, words or lines |
|
||||
| `find <directory> [options]` | search files (Ex: `find . -name '*.txt'`) |
|
||||
| `sed <command> <filename>` | process file line by line for basic editing |
|
||||
| `grep [options] <regular expression> <filenames>` | search files for a *pattern* |
|
||||
| `egrep [options] <extended regular expression> <filenames>` | similar as using the `-e` option of `grep` |
|
||||
|
||||
## `Unix` streams
|
||||
|
||||
> In computer programming, standard streams are pre-connected input and output channels that allow communication between a computer program and its environment when the program begins execution.
|
||||
> The three I/O connections are called standard input (`stdin`), standard output (`stdout`) and standard error (`stderr`).
|
||||
|
||||
A basic `Unix` command: Piping a stream into another command> [wikipedia:streams](https://en.wikipedia.org/wiki/Standard_streams)
|
||||
|
||||
## A basic `Unix` command
|
||||
|
||||
{ width=50% }
|
||||
|
||||
standard input (`stdin`), standard output (`stdout`), standard error (`stderr`) and parameters don't need to be specified.
|
||||
|
||||
By default, `stdin` is empty, `stdout` and `stderr` output their content to the terminal.
|
||||
|
||||
## A basic `Unix` command: Specifying parameters
|
||||
|
||||
#### Exemples: Parameters
|
||||
|
||||
```bash
|
||||
grep -B 2 root /etc/passwd
|
||||
```
|
||||
|
||||
{ width=60% }
|
||||
|
||||
## A basic `Unix` command: Sending the content of a text file to the standard input
|
||||
|
||||
Most of the commands that handle text can, if no file is given as a parameter, use the content of `stdin`.
|
||||
|
||||
#### Exemples: Redirecting the standard input
|
||||
|
||||
```bash
|
||||
grep -B 2 root < /etc/passwd
|
||||
```
|
||||
|
||||
{ width=40% }
|
||||
|
||||
## A basic `Unix` command: Creating a text file from the output of a command
|
||||
|
||||
### Exemples: Redirecting the standard output
|
||||
|
||||
```bash
|
||||
# > create or replace file
|
||||
# >> append to file
|
||||
grep -B 2 root < /etc/passwd > result
|
||||
```
|
||||
|
||||
{ width=20% }
|
||||
|
||||
## A basic `Unix` command: Piping a stream into another command
|
||||
|
||||
### Exemples: Redirecting the standard output
|
||||
|
||||
```bash
|
||||
# > create or replace file
|
||||
# >> append to file
|
||||
grep -B 2 root < /etc/passwd | less
|
||||
```
|
||||
|
||||
{ width=20% }
|
||||
|
||||
## RTFM: Bash redirections
|
||||
|
||||
[Bash redirections](https://www.gnu.org/software/bash/manual/html_node/Redirections.html)
|
||||
|
||||
# The bash command challenge !
|
||||
|
||||
|
||||
{ width=80% }
|
||||
|
||||
|
||||
[I accept the challenge !](https://cmdchallenge.com/)
|
||||
|
||||
|
||||
|
||||
975
web_src/05_Lectures/00_Computers/unix/unix-modern-bash.qmd
Normal file
@@ -0,0 +1,975 @@
|
||||
---
|
||||
title: "Introduction to Unix by Example"
|
||||
subtitle: "A Modern Approach for Bioinformaticians"
|
||||
author: "Updated Course Material"
|
||||
date: today
|
||||
format:
|
||||
html:
|
||||
toc: true
|
||||
toc-depth: 3
|
||||
number-sections: true
|
||||
code-fold: false
|
||||
theme: cosmo
|
||||
---
|
||||
|
||||
# Why Unix?
|
||||
|
||||
The Unix operating system was born in AT&T laboratories in the United States, then known as "Bell Labs". Created in the late 1960s, it derives from Multics, another system from the same laboratory about ten years earlier. Unix spread rapidly because Bell Labs distributed its new system as freely modifiable source code. This led to the emergence of Unix families produced by the system's main users: research laboratories on one hand and major computer manufacturers on the other.
|
||||
|
||||
From the beginning, Unix development has been closely linked to scientific computing. These intrinsic qualities explain why this operating system is still widely used in many research fields today.
|
||||
|
||||
Today, Unix is a registered trademark of The Open Group, which standardizes all Unix systems. However, there is a broader definition that includes "Unix-like" systems such as GNU/Linux. Despite proclaiming in its name not to be Unix (GNU is Not Unix), this family of operating systems has such functional similarities with its ancestor that it's difficult to explain how it isn't Unix.
|
||||
|
||||
Nowadays, a Unix system can be installed on virtually any machine, from personal computers to large computing servers. Notably, for several years, Apple's standard operating system on Macintosh computers, macOS, has been a certified Unix system.
|
||||
|
||||
# Unix System Overview
|
||||
|
||||
Unix is a multitasking and multi-user operating system. This means it can manage the simultaneous use of the same computer by multiple people, and for each person, it allows parallel execution of multiple programs. The multiplicity of users and running programs on the same machine requires particular resource management, involving restricted rights for each user so that one person's work doesn't interfere with another's.
|
||||
|
||||
```{mermaid}
|
||||
flowchart TB
|
||||
U1["User 1"] --> S1["Shell<br/>(Command Interpreter)"]
|
||||
U2["User 2"] --> S1
|
||||
U3["User N"] --> S1
|
||||
|
||||
subgraph Unix ["Unix Operating System"]
|
||||
S1["Shell<br/>(Command Interpreter)"] --> K1["Kernel<br/>(Core System)"]
|
||||
K1 --> R1["CPU"]
|
||||
K1 --> R2["Memory"]
|
||||
K1 --> R3["Disk Storage"]
|
||||
K1 --> R4["Network"]
|
||||
end
|
||||
```
|
||||
|
||||
## Users
|
||||
|
||||
Each Unix system user needs an account or "machine access right" to work. Each account is identified by a login name.
|
||||
|
||||
Associated with each login:
|
||||
|
||||
- A password that secures system access
|
||||
- A user ID (UID) that identifies the user on the machine
|
||||
- A location on the hard drive to store user files, called Home directory
|
||||
- A user group, allowing collaborative work (see later)
|
||||
|
||||
Information about all users on a machine is typically stored in a text file: `/etc/passwd`
|
||||
|
||||
```bash
|
||||
root:x:0:0:root:/root:/bin/bash
|
||||
bin:x:1:1:bin:/bin:/sbin/nologin
|
||||
daemon:x:2:2:daemon:/sbin:/sbin/nologin
|
||||
mail:x:8:12:mail:/var/spool/mail:/sbin/nologin
|
||||
alice:x:1000:1000:Alice Smith:/home/alice:/bin/bash
|
||||
bob:x:1001:1001:Bob Jones:/home/bob:/bin/bash
|
||||
```
|
||||
|
||||
Each line corresponds to a user. Information is separated by `:` characters. In order: login, encoded password, UID, group ID, full name, home directory, and default shell.
|
||||
|
||||
## The File System
|
||||
|
||||
The file system of an operating system encompasses all mechanisms for managing storage space (hard drives) on the computer. Data and programs are stored in files. A file can be thought of as a small part of a hard drive dedicated to storing a set of data.
|
||||
|
||||
### File Names
|
||||
|
||||
In a Unix system, a file name describes a path in a tree. A file name starts with a `/` character and consists of successive node labels describing the file's location in the name tree. Each label is separated from the preceding one by the `/` character.
|
||||
|
||||
```{mermaid}
|
||||
graph TB
|
||||
root["/"]
|
||||
root --> bin["/bin"]
|
||||
root --> etc["/etc"]
|
||||
root --> home["/home"]
|
||||
root --> usr["/usr"]
|
||||
root --> var["/var"]
|
||||
|
||||
etc --> passwd["passwd"]
|
||||
etc --> hosts["hosts"]
|
||||
|
||||
home --> alice["alice"]
|
||||
home --> bob["bob"]
|
||||
|
||||
alice --> documents["documents"]
|
||||
alice --> data["data.txt"]
|
||||
|
||||
usr --> local["/local"]
|
||||
usr --> usrbin["/bin"]
|
||||
|
||||
style passwd fill:#e1f5ff
|
||||
style root fill:#ffe1e1
|
||||
```
|
||||
|
||||
For example, the file `/etc/passwd` indicates that this file is located at a node (directory) named `/etc`, which itself is located at the root of the file name tree `/`.
|
||||
|
||||
### Standard Directory Structure
|
||||
|
||||
Certain directories are found in many Unix systems:
|
||||
|
||||
- `/etc` - Contains system configuration files
|
||||
- `/var` - Contains system operation information
|
||||
- `/bin` - Contains basic system programs
|
||||
- `/usr` - Contains a large part of the system
|
||||
- `/usr/local` - Contains programs specific to a machine
|
||||
- `/home` - Contains user home directories
|
||||
- `/tmp` - Temporary files
|
||||
|
||||
### Lexical Rules for File Names
|
||||
|
||||
File name labels can contain:
|
||||
|
||||
- Alphabetic characters (a-z and A-Z)
|
||||
- Numeric characters (0-9)
|
||||
- Punctuation marks (& , $ , * , + , = , . , etc.)
|
||||
|
||||
However, using some of these signs can cause problems. It's recommended to use only: `. , % , - , _ , : , =`
|
||||
|
||||
**Important**: Unix is case-sensitive. `TODO`, `todo`, `Todo`, and `ToTo` are all different names.
|
||||
|
||||
File names starting with a dot `.` are hidden files and typically correspond to configuration files.
|
||||
|
||||
### Links
|
||||
|
||||
The concept of a link can be compared to a shortcut in other operating systems. A link is a special file that creates additional edges in the file name tree. From a computer science perspective, the tree structure becomes a Directed Acyclic Graph (DAG).
|
||||
|
||||
```{mermaid}
|
||||
graph LR
|
||||
root["/"]
|
||||
usr["/usr"]
|
||||
bin["/bin"]
|
||||
home["/home"]
|
||||
alice["alice"]
|
||||
programs["programs<br/>(link)"]
|
||||
grep["grep"]
|
||||
|
||||
root --> usr
|
||||
root --> home
|
||||
usr --> bin
|
||||
home --> alice
|
||||
alice --> programs
|
||||
bin --> grep
|
||||
programs -.->|symbolic link| bin
|
||||
|
||||
style programs fill:#fff2cc
|
||||
style grep fill:#e1f5ff
|
||||
```
|
||||
|
||||
Creating a link in a Unix file system creates a synonym between the link name and the target file.
|
||||
|
||||
### The `.` and `..` Directories
|
||||
|
||||
Unix uses links to facilitate navigation in the file name tree. When creating a directory node, the system automatically adds two links under this node named `.` and `..`:
|
||||
|
||||
- `.` links to the directory containing it
|
||||
- `..` points to the parent directory
|
||||
|
||||
```{mermaid}
|
||||
graph TB
|
||||
root["/"]
|
||||
home["/home"]
|
||||
alice["alice"]
|
||||
dot[". (alice)"]
|
||||
dotdot[".. (home)"]
|
||||
docs["documents"]
|
||||
|
||||
root --> home
|
||||
home --> alice
|
||||
alice --> dot
|
||||
alice --> dotdot
|
||||
alice --> docs
|
||||
|
||||
dot -.-> alice
|
||||
dotdot -.-> home
|
||||
|
||||
style dot fill:#fff2cc
|
||||
style dotdot fill:#fff2cc
|
||||
```
|
||||
|
||||
These links mean that for each file, there isn't just one name but an infinite number of possible names. The file `/home/alice/myfile` can also be named:
|
||||
|
||||
- `/home/alice/./myfile`
|
||||
- `/home/alice/../../home/alice/myfile`
|
||||
- `/home/alice/./././myfile`
|
||||
|
||||
### Current Directory and Relative Paths
|
||||
|
||||
The hierarchical tree structure of Unix file names is powerful but produces often very long file names. To work around this problem, Unix offers the concept of current directory and relative paths.
|
||||
|
||||
**Current Directory**: When working on a machine, you typically work on a set of files located in the same region of the name tree. The common part of all these names is stored in an environment variable called `PWD` (Present Working Directory).
|
||||
|
||||
By default, when you log into your Unix account, this variable is initialized with your home directory name. You can change this variable's value using the `cd` command.
|
||||
|
||||
**Relative Paths**: Relative file names are expressed relative to the current directory. To know the true name corresponding to a relative name, you concatenate the current directory name and the relative name.
|
||||
|
||||
Example:
|
||||
```bash
|
||||
# If current directory is: /home/alice/experiment_1
|
||||
# These files:
|
||||
/home/alice/experiment_1/sequence.fasta
|
||||
/home/alice/experiment_1/expression.dat
|
||||
/home/alice/experiment_1/annotation.gff
|
||||
|
||||
# Can be named simply:
|
||||
sequence.fasta
|
||||
expression.dat
|
||||
annotation.gff
|
||||
```
|
||||
|
||||
A relative name is recognized by the fact it doesn't start with `/`. In contrast, complete file names are called absolute paths and always start with `/`.
|
||||
|
||||
### Access Rights
|
||||
|
||||
Unix is a multi-user system. To protect each user's data from others, each file belongs to a specific user (usually its creator) and a user group. Additionally, each file has access rights concerning:
|
||||
|
||||
- The file owner
|
||||
- The group to which the file belongs
|
||||
- All other system users
|
||||
|
||||
For each of these three user categories, there are read, write, and execute rights:
|
||||
|
||||
- **Read right**: Allows reading the file
|
||||
- **Write right**: Authorizes modifying or deleting the file
|
||||
- **Execute right**: Allows executing the file if it contains a program
|
||||
|
||||
For directories, execute right indicates permission to use it as an element of a file name.
|
||||
|
||||
```bash
|
||||
# Example of file permissions
|
||||
$ ls -l
|
||||
-rw-r--r-- 1 alice staff 1024 Nov 03 10:30 data.txt
|
||||
-rwxr-xr-x 1 alice staff 2048 Nov 03 10:31 script.sh
|
||||
drwxr-xr-x 2 alice staff 512 Nov 03 10:32 results
|
||||
```
|
||||
|
||||
Rights can be modified by the file owner using the `chmod` instruction.
|
||||
|
||||
## Processes
|
||||
|
||||
A program corresponds to a sequence of calculation instructions that the computer must execute to perform a task. While it's important to store this instruction sequence for regular reuse, it's equally important to execute it. A process corresponds to the execution of a program.
|
||||
|
||||
Since Unix is multitasking and multi-user, the same program can be executed simultaneously by multiple processes. It's therefore important to distinguish between program and process.
|
||||
|
||||
### Process Anatomy
|
||||
|
||||
A process can be considered as part of the computer's memory dedicated to program execution. This memory chunk can be divided into three main parts: the environment, data area, and program area.
|
||||
|
||||
```{mermaid}
|
||||
flowchart TB
|
||||
subgraph Process["Process Memory Space"]
|
||||
direction TB
|
||||
Env["Environment<br/>- Variables<br/>- File descriptors<br/>- PID/PPID"]
|
||||
Code["Code Area<br/>- Program instructions"]
|
||||
Data["Data Area<br/>- Variables<br/>- Computation results"]
|
||||
end
|
||||
|
||||
Parent["Parent Process"] -.->|fork| Process
|
||||
|
||||
style Env fill:#e1f5ff
|
||||
style Code fill:#ffe1e1
|
||||
style Data fill:#e1ffe1
|
||||
```
|
||||
|
||||
### Process Environment
|
||||
|
||||
A process is an isolated memory area where a program executes. Isolation secures the computer by preventing a program from corrupting others' execution. However, during execution, a program must interact with the rest of the computer.
|
||||
|
||||
The process environment is dedicated to this interface task. It contains descriptions of system elements the process needs to know. Two main types of information are stored:
|
||||
|
||||
**Environment Variables**: Associate a name with a value describing certain system properties. Examples:
|
||||
|
||||
- `PWD`: Current Working Directory for interpreting relative paths
|
||||
- `PATH`: List of directories where available programs are stored
|
||||
- `HOME`: User's home directory
|
||||
- `USER`: Current username
|
||||
|
||||
**Streams**: Virtual pipes through which data transits. By default, three streams are associated with each process:
|
||||
|
||||
- `stdin` (standard input): How a Unix program normally receives data
|
||||
- `stdout` (standard output): Used by the program to return results
|
||||
- `stderr` (standard error): Used for error messages and information
|
||||
|
||||
```{mermaid}
|
||||
flowchart LR
|
||||
Input[("Input<br/>Source")] --> stdin["stdin<br/>(0)"]
|
||||
stdin --> Process["Process"]
|
||||
Process --> stdout["stdout<br/>(1)"]
|
||||
Process --> stderr["stderr<br/>(2)"]
|
||||
stdout --> Output[("Output<br/>Destination")]
|
||||
stderr --> Error[("Error<br/>Log")]
|
||||
|
||||
style stdin fill:#e1f5ff
|
||||
style stdout fill:#e1ffe1
|
||||
style stderr fill:#ffe1e1
|
||||
```
|
||||
|
||||
### Process Lifecycle
|
||||
|
||||
Every process has a parent (except the initial process) and inherits all its properties: environment, data area, and program code to execute.
|
||||
|
||||
```{mermaid}
|
||||
stateDiagram-v2
|
||||
[*] --> Init: System Boot
|
||||
Init --> Parent: fork()
|
||||
Parent --> Child1: fork()
|
||||
Parent --> Child2: fork()
|
||||
Child1 --> [*]: exit()
|
||||
Child2 --> [*]: exit()
|
||||
Parent --> [*]: All children terminated
|
||||
|
||||
note right of Parent
|
||||
PID: 1234
|
||||
Creates child processes
|
||||
end note
|
||||
|
||||
note right of Child1
|
||||
PID: 1235
|
||||
Inherits parent environment
|
||||
end note
|
||||
```
|
||||
|
||||
Important points:
|
||||
|
||||
- Every process has a parent and inherits all its properties
|
||||
- A child process must terminate before its parent
|
||||
- When you close your shell, all running programs are terminated unless detached
|
||||
- A process is created by copying its parent, inheriting its properties except PID
|
||||
|
||||
The normal chronology for creating a new process:
|
||||
|
||||
1. Call the `fork()` function
|
||||
2. Test which process continues execution
|
||||
3. In the child process, call `exec()` to replace the program code
|
||||
4. At execution end, notify the parent and wait for cleanup
|
||||
|
||||
# The Unix Shell - A Working Environment
|
||||
|
||||
The Unix shell is the most important program for a Unix user. It's how they interact with their computer. There's a graphical window system under Unix similar to Windows or macOS, called X Window System (X11), which can operate in client/server mode across networks. However, we'll focus on interacting with Unix in "text" mode via the shell.
|
||||
|
||||
The Unix shell is a program capable of interpreting a command language. These commands allow users to launch program execution by specifying:
|
||||
|
||||
- Data to work on
|
||||
- Parameters to adjust execution
|
||||
- What to do with results
|
||||
|
||||
Several Unix shells exist, differing mainly in their command language syntax. The two most commonly used today are:
|
||||
|
||||
- **bash** (Bourne Again Shell): Modern version of the Bourne shell (sh)
|
||||
- **zsh** (Z Shell): Enhanced version with additional features
|
||||
|
||||
This course focuses on **bash**, the default shell on most Linux systems and macOS.
|
||||
|
||||
## Basic Command Structure
|
||||
|
||||
A shell command describes how to trigger program execution with all necessary information. As a principle, every program installed on a Unix machine corresponds to a usable command from the shell bearing the program's name, and conversely, every Unix command is the name of an installed program.
|
||||
|
||||
```{mermaid}
|
||||
flowchart LR
|
||||
Command["Command<br/>(program name)"] --> Options["Options<br/>(flags)"]
|
||||
Options --> Arguments["Arguments<br/>(input files)"]
|
||||
Arguments --> Redirection["I/O Redirection<br/>(< > |)"]
|
||||
|
||||
style Command fill:#ffe1e1
|
||||
style Options fill:#e1f5ff
|
||||
style Arguments fill:#e1ffe1
|
||||
style Redirection fill:#fff2cc
|
||||
```
|
||||
|
||||
A Unix command line has four main parts:
|
||||
|
||||
1. **Command** (required): Program name
|
||||
2. **Options** (optional): Adjust program behavior
|
||||
3. **Arguments** (optional): Specify data to process
|
||||
4. **Redirection** (optional): Control input/output
|
||||
|
||||
### The Unix Command
|
||||
|
||||
A Unix command is the name of a program installed on the machine. When you execute a command like `ls` or `grep`, you're actually launching execution of an eponymous program stored somewhere on your hard drives.
|
||||
|
||||
The machine searches for program files only in a subset of existing directories, described by a list stored in the `PATH` environment variable.
|
||||
|
||||
```bash
|
||||
$ echo $PATH
|
||||
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
||||
```
|
||||
|
||||
Directories are searched in order. If programs with the same name exist in different directories, the first one found is executed.
|
||||
|
||||
To execute a program in a directory not listed in `PATH`, specify its location:
|
||||
|
||||
```bash
|
||||
# Using absolute path
|
||||
$ /home/alice/myprograms/myscript.sh
|
||||
|
||||
# Using relative path (if in the directory)
|
||||
$ ./myscript.sh
|
||||
```
|
||||
|
||||
The `./` prefix is necessary to indicate the current directory location.
|
||||
|
||||
### Command Options
|
||||
|
||||
Options alter command functionality by adjusting parameters. Options are recognizable as:
|
||||
|
||||
- Short form: Single character preceded by `-` (e.g., `-l`)
|
||||
- Long form: Complete word preceded by `--` (e.g., `--list`)
|
||||
|
||||
Many programs offer both forms for the same option.
|
||||
|
||||
```bash
|
||||
# Short option
|
||||
$ grep -i root /etc/passwd
|
||||
|
||||
# Long option (equivalent)
|
||||
$ grep --ignore-case root /etc/passwd
|
||||
```
|
||||
|
||||
Some options require arguments:
|
||||
|
||||
```bash
|
||||
# Short form with argument
|
||||
$ grep -B 2 root /etc/passwd
|
||||
$ grep -B2 root /etc/passwd # No space also works
|
||||
|
||||
# Long form with argument
|
||||
$ grep --before-context=2 root /etc/passwd
|
||||
```
|
||||
|
||||
Multiple short options can be combined:
|
||||
|
||||
```bash
|
||||
# Separate options
|
||||
$ grep -i -n root /etc/passwd
|
||||
|
||||
# Combined options
|
||||
$ grep -in root /etc/passwd
|
||||
```
|
||||
|
||||
If an option requires an argument, it must be placed last in the group.
|
||||
|
||||
### Command Arguments
|
||||
|
||||
Arguments indicate data the program should process, beyond data potentially transmitted through standard input. Depending on how it's programmed, a program can accept one or multiple arguments. Each argument may have a distinct role depending on the program.
|
||||
|
||||
To understand each argument's role, consult the program's manual page via `man` command or online help, usually accessible with the `-h` option.
|
||||
|
||||
```bash
|
||||
# Example with multiple arguments
|
||||
$ cp source.txt destination.txt
|
||||
|
||||
# Example with patterns
|
||||
$ grep "pattern" file1.txt file2.txt file3.txt
|
||||
```
|
||||
|
||||
### I/O Redirection Instructions
|
||||
|
||||
This fourth part of a Unix command line is crucial, allowing you to specify how your program should configure its standard inputs/outputs. This is one of the most important things to understand to fully benefit from the Unix system.
|
||||
|
||||
## File Name Patterns with Wildcards
|
||||
|
||||
It's very common in a Unix command to need to specify multiple file names. When the number of files becomes large, typing these names one by one can be tedious, especially if all file names share common characteristics.
|
||||
|
||||
To address this, there's a series of "wildcard" characters to indicate the form of desired file names:
|
||||
|
||||
| Wildcard | Matches |
|
||||
|----------|---------|
|
||||
| `*` | Zero, one, or more characters |
|
||||
| `?` | Exactly one character |
|
||||
| `[...]` | One character from the list |
|
||||
| `[^...]` | One character NOT in the list |
|
||||
| `[a-z]` | One character in the range |
|
||||
|
||||
Each word in a Unix command line using these characters is replaced during execution by the list of existing file names matching the pattern.
|
||||
|
||||
```bash
|
||||
# List all text files
|
||||
$ ls *.txt
|
||||
|
||||
# Files starting with 'data' and any single character
|
||||
$ ls data?
|
||||
|
||||
# Files starting with uppercase letter
|
||||
$ ls [A-Z]*
|
||||
|
||||
# Files NOT starting with lowercase letter
|
||||
$ ls [^a-z]*
|
||||
|
||||
# Complex pattern
|
||||
$ ls experiment_[0-9][0-9].dat
|
||||
```
|
||||
|
||||
If no file matches the pattern, a "No match" error is generated.
|
||||
|
||||
```bash
|
||||
$ echo *toto
|
||||
bash: no matches found: *toto
|
||||
|
||||
$ ls /
|
||||
Applications Library bin home opt usr
|
||||
Desktop Network cores sbin private var
|
||||
Developer System dev etc tmp
|
||||
|
||||
$ echo /mach*
|
||||
/mach.sym /mach_kernel /mach_kernel.ctfsys
|
||||
|
||||
$ echo /*.*
|
||||
/atp.mol /mach.sym /mach_kernel.ctfsys /untitled.log
|
||||
|
||||
$ echo /[AD]*
|
||||
/Applications /Desktop_DB /Desktop_DF /Developer
|
||||
|
||||
$ echo /[uv]??
|
||||
/usr /var
|
||||
```
|
||||
|
||||
These file name patterns are most often used with file manipulation commands like copying (`cp`), deletion (`rm`), or listing (`ls`). They're also frequently used in loops to launch the same command on an entire series of datasets.
|
||||
|
||||
## Standard I/O Redirection
|
||||
|
||||
The property that gives a Unix shell its full power is the standard input/output redirection system. Each process inherits three standard data streams from its parent:
|
||||
|
||||
- `stdin`: Standard input stream (file descriptor 0)
|
||||
- `stdout`: Standard output stream (file descriptor 1)
|
||||
- `stderr`: Standard error stream (file descriptor 2)
|
||||
|
||||
```{mermaid}
|
||||
flowchart TB
|
||||
subgraph Default["Default Configuration"]
|
||||
Keyboard[("Keyboard")] --> stdin1["stdin"]
|
||||
stdin1 --> Shell1["Shell Process"]
|
||||
Shell1 --> stdout1["stdout"]
|
||||
Shell1 --> stderr1["stderr"]
|
||||
stdout1 --> Screen1[("Screen")]
|
||||
stderr1 --> Screen1
|
||||
end
|
||||
|
||||
style stdin1 fill:#e1f5ff
|
||||
style stdout1 fill:#e1ffe1
|
||||
style stderr1 fill:#ffe1e1
|
||||
```
|
||||
|
||||
### Redirecting Standard Output
|
||||
|
||||
To save results generated by a program to a file, add an output redirection instruction at the end of the command line: `>` followed by a file name.
|
||||
|
||||
```bash
|
||||
$ ls /
|
||||
Applications Desktop Developer Library System
|
||||
bin cores dev etc home usr var
|
||||
|
||||
$ ls / > my_listing
|
||||
|
||||
$ ls -l
|
||||
total 8
|
||||
drwxr-xr-x 2 alice staff 102 Nov 27 17:18 myprograms
|
||||
-rw-r--r-- 1 alice staff 241 Dec 3 16:50 my_listing
|
||||
|
||||
$ cat my_listing
|
||||
Applications
|
||||
Desktop
|
||||
Developer
|
||||
Library
|
||||
System
|
||||
bin
|
||||
cores
|
||||
dev
|
||||
etc
|
||||
home
|
||||
usr
|
||||
var
|
||||
```
|
||||
|
||||
```{mermaid}
|
||||
flowchart LR
|
||||
stdin["stdin"] --> Process["ls /"]
|
||||
Process --> stdout["stdout"]
|
||||
Process --> stderr["stderr"]
|
||||
stdout --> File[("my_listing")]
|
||||
stderr --> Screen[("Screen")]
|
||||
|
||||
style stdout fill:#e1ffe1
|
||||
style stderr fill:#ffe1e1
|
||||
```
|
||||
|
||||
Important notes:
|
||||
|
||||
- If the file doesn't exist, it's created and filled with results
|
||||
- If the file exists, it's erased and replaced with a new file
|
||||
- **Be careful**: This can easily overwrite existing files
|
||||
|
||||
To append results to an existing file instead of replacing it, use `>>`:
|
||||
|
||||
```bash
|
||||
$ echo "First line" > output.txt
|
||||
$ echo "Second line" >> output.txt
|
||||
$ cat output.txt
|
||||
First line
|
||||
Second line
|
||||
```
|
||||
|
||||
### Redirecting Standard Input
|
||||
|
||||
Input redirection indicates where a program reading from standard input should find its data. Input redirection uses the `<` character.
|
||||
|
||||
```bash
|
||||
$ grep or < my_listing
|
||||
Network
|
||||
cores
|
||||
|
||||
$ grep or < my_listing > my_selection
|
||||
|
||||
$ cat my_selection
|
||||
Network
|
||||
cores
|
||||
```
|
||||
|
||||
The `grep` command selects lines of text containing a pattern (or in this example) and copies them to standard output. Input redirection tells the process to read from `my_listing`, and output redirection saves results to `my_selection`.
|
||||
|
||||
### Redirecting Output to Another Process (Pipes)
|
||||
|
||||
The most powerful redirection mode connects one process's standard output to another's standard input. The first program's results become the second's data. Data passes directly between processes without going through an intermediate file. This creates a "pipe" between processes.
|
||||
|
||||
```{mermaid}
|
||||
flowchart LR
|
||||
stdin1["stdin"] --> P1["ls /"]
|
||||
P1 --> pipe["|<br/>pipe"]
|
||||
pipe --> P2["grep or"]
|
||||
P2 --> stdout2["stdout"]
|
||||
P2 --> stderr2["stderr"]
|
||||
stdout2 --> Screen[("Screen")]
|
||||
stderr2 --> Screen
|
||||
|
||||
style pipe fill:#fff2cc
|
||||
style stdout2 fill:#e1ffe1
|
||||
style stderr2 fill:#ffe1e1
|
||||
```
|
||||
|
||||
Syntactically, this is achieved by joining two or more commands with the `|` character:
|
||||
|
||||
```bash
|
||||
$ ls / | grep or
|
||||
Network
|
||||
cores
|
||||
|
||||
$ ls / | grep or > my_selection
|
||||
|
||||
$ cat my_selection
|
||||
Network
|
||||
cores
|
||||
```
|
||||
|
||||
In a complex command, a process is created for each command, and data simply transits from one to another.
|
||||
|
||||
**Important restrictions:**
|
||||
|
||||
- Commands before a pipe cannot redirect stdout to a file (already piped to next command)
|
||||
- Commands after a pipe cannot redirect stdin from a file (already receiving from previous command)
|
||||
|
||||
You can chain multiple pipes:
|
||||
|
||||
```bash
|
||||
# Count lines containing "error" in log file
|
||||
$ cat logfile.txt | grep error | wc -l
|
||||
|
||||
# Sort unique email addresses
|
||||
$ cat emails.txt | sort | uniq
|
||||
```
|
||||
|
||||
## Building Execution Loops
|
||||
|
||||
A computer's value lies in its ability to automatically perform repetitive calculation tasks. Users often find themselves needing to launch the same Unix command for calculations on multiple datasets. If each dataset is saved in a different file with coherent naming (e.g., `gis_vercors.dat`, `gis_belledonne.dat`, `gis_chartreuse.dat`), it's possible to leverage loop structures offered by Unix shells.
|
||||
|
||||
### Shell Variables
|
||||
|
||||
Working automatically and repetitively requires using variables to store useful, changing information at each iteration. For example, if your Unix command must read data from different files for each execution, you cannot write the file name in your command since it won't always be the same.
|
||||
|
||||
You already know environment variables, set up by the `export` command, used to store system configuration information. There are simple variables allowing you to store any information you deem necessary during your Unix session. They're set up with simple assignment:
|
||||
|
||||
```bash
|
||||
$ myvar="hello everyone"
|
||||
$ echo myvar
|
||||
myvar
|
||||
$ echo $myvar
|
||||
hello everyone
|
||||
```
|
||||
|
||||
To retrieve the value contained in a variable, precede its name with the `$` character.
|
||||
|
||||
### The `for` Loop
|
||||
|
||||
To solve our problem of repeating the same Unix command multiple times while working on different data files, we'll create a variable that takes each element of a list as its value in turn. In our case, this list will be a list of file names constructed using file name ambiguity characters.
|
||||
|
||||
```bash
|
||||
$ echo /[mnop]*
|
||||
/mach.sym /mach_kernel /mach_kernel.ctfsys /net /opt /private
|
||||
|
||||
$ for f in /[mnop]*; do
|
||||
> echo "Working with file $f"
|
||||
> done
|
||||
Working with file /mach.sym
|
||||
Working with file /mach_kernel
|
||||
Working with file /mach_kernel.ctfsys
|
||||
Working with file /net
|
||||
Working with file /opt
|
||||
Working with file /private
|
||||
```
|
||||
|
||||
```{mermaid}
|
||||
flowchart TD
|
||||
Start([Start]) --> Init["Initialize loop variable<br/>with first item"]
|
||||
Init --> Check{More items<br/>in list?}
|
||||
Check -->|Yes| Execute["Execute commands<br/>in loop body"]
|
||||
Execute --> Next["Move to next item"]
|
||||
Next --> Check
|
||||
Check -->|No| End([End])
|
||||
|
||||
style Execute fill:#e1ffe1
|
||||
```
|
||||
|
||||
The syntax is:
|
||||
|
||||
```bash
|
||||
for variable in list; do
|
||||
commands using $variable
|
||||
done
|
||||
```
|
||||
|
||||
All Unix commands inserted between `do` and `done` are executed once for each value taken by the variable.
|
||||
|
||||
Practical examples:
|
||||
|
||||
```bash
|
||||
# Process multiple data files
|
||||
$ for file in data*.txt; do
|
||||
> echo "Processing $file"
|
||||
> ./analyze.sh $file > results_$file
|
||||
> done
|
||||
|
||||
# Rename multiple files
|
||||
$ for file in *.jpeg; do
|
||||
> mv "$file" "${file%.jpeg}.jpg"
|
||||
> done
|
||||
|
||||
# Create numbered directories
|
||||
$ for i in {1..10}; do
|
||||
> mkdir experiment_$i
|
||||
> done
|
||||
```
|
||||
|
||||
### Conditional Execution
|
||||
|
||||
Bash also provides conditional structures:
|
||||
|
||||
```bash
|
||||
# if-then-else
|
||||
$ if [ -f "data.txt" ]; then
|
||||
> echo "File exists"
|
||||
> else
|
||||
> echo "File not found"
|
||||
> fi
|
||||
|
||||
# Test file properties
|
||||
$ for file in *.txt; do
|
||||
> if [ -s "$file" ]; then
|
||||
> echo "$file is not empty"
|
||||
> fi
|
||||
> done
|
||||
```
|
||||
|
||||
Common test operators:
|
||||
|
||||
| Test | Meaning |
|
||||
|------|---------|
|
||||
| `-f file` | File exists and is regular file |
|
||||
| `-d dir` | Directory exists |
|
||||
| `-s file` | File exists and is not empty |
|
||||
| `-r file` | File is readable |
|
||||
| `-w file` | File is writable |
|
||||
| `-x file` | File is executable |
|
||||
|
||||
# Essential Unix Commands (Alphabetical)
|
||||
|
||||
The commands presented here are a subset of all commands available by default on a Unix system. They're presented with a subset of their options. For a complete description of their functionality, refer to online help accessible via the `man` command.
|
||||
|
||||
## `awk` - Pattern Scanning and Processing
|
||||
|
||||
Named after its authors (Aho, Weinberger, Kernighan), `awk` is a complete programming language. A full description is beyond this course's scope but was perfectly described in "The AWK Programming Language" by its authors.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
awk [-F separator] 'program' [data_file]
|
||||
```
|
||||
|
||||
**Main options:**
|
||||
|
||||
- `-F` - Specify column separator
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Print second column
|
||||
$ awk '{print $2}' file.txt
|
||||
|
||||
# Sum numbers in first column
|
||||
$ awk '{sum += $1} END {print sum}' numbers.txt
|
||||
|
||||
# Process CSV file
|
||||
$ awk -F',' '{print $1, $3}' data.csv
|
||||
```
|
||||
|
||||
## `bash` - Bourne-Again Shell
|
||||
|
||||
Launches a bash Unix shell. To exit this new shell, press `Ctrl-D` at a prompt.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
bash
|
||||
```
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
$ bash
|
||||
bash-5.1$ export test_var="hello"
|
||||
bash-5.1$ exit
|
||||
$
|
||||
```
|
||||
|
||||
## `bg` - Send Process to Background
|
||||
|
||||
Resumes execution of a process suspended by `Ctrl-Z` in the background.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
bg [%job]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `%job` - Job number (preceded by %). Get list with `jobs` command.
|
||||
|
||||
**Example:**
|
||||
```bash
|
||||
$ sleep 30
|
||||
^Z
|
||||
[1]+ Stopped sleep 30
|
||||
$ jobs
|
||||
[1]+ Stopped sleep 30
|
||||
$ bg %1
|
||||
[1]+ sleep 30 &
|
||||
$ jobs
|
||||
[1]+ Running sleep 30 &
|
||||
```
|
||||
|
||||
## `cat` - Concatenate Files
|
||||
|
||||
Reads content from one or more data streams and copies it identically to standard output.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
cat [file ...]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `file` - One or more file names. If none provided, reads from stdin.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Display file content
|
||||
$ cat file.txt
|
||||
|
||||
# Concatenate multiple files
|
||||
$ cat file1.txt file2.txt > combined.txt
|
||||
|
||||
# Number lines
|
||||
$ cat -n file.txt
|
||||
```
|
||||
|
||||
## `cd` - Change Directory
|
||||
|
||||
Changes the current working directory.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
cd [directory]
|
||||
```
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `directory` - New working directory name. Without argument, returns to home.
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
$ pwd
|
||||
/home/alice
|
||||
$ cd /usr/local
|
||||
$ pwd
|
||||
/usr/local
|
||||
$ cd ../../home/alice
|
||||
$ pwd
|
||||
/home/alice
|
||||
$ cd
|
||||
$ pwd
|
||||
/home/alice
|
||||
```
|
||||
|
||||
## `chmod` - Change File Mode
|
||||
|
||||
Changes file access permissions.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
chmod [-R] mode file
|
||||
```
|
||||
|
||||
**Main options:**
|
||||
|
||||
- `-R` - Recursive operation on directory contents
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `mode` - Permission change description (e.g., `u+x`, `go-w`, `755`)
|
||||
- `file` - File(s) whose mode should be changed
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Add execute permission for user
|
||||
$ chmod u+x script.sh
|
||||
|
||||
# Remove write permission for group and others
|
||||
$ chmod go-w data.txt
|
||||
|
||||
# Set specific permissions with octal
|
||||
$ chmod 755 program
|
||||
|
||||
# Recursive permission change
|
||||
$ chmod -R 644 documents/
|
||||
```
|
||||
|
||||
## `cp` - Copy Files
|
||||
|
||||
Copies a file or directory.
|
||||
|
||||
**Synopsis:**
|
||||
```bash
|
||||
cp [-R] source destination
|
||||
```
|
||||
|
||||
**Main options:**
|
||||
|
||||
- `-R` - Recursive copy for directories
|
||||
|
||||
**Arguments:**
|
||||
|
||||
- `source` - File(s) to be copied
|
||||
- `destination` - Copy destination name or directory
|
||||
|
||||
**Examples:**
|
||||
```bash
|
||||
# Copy file
|
||||
$ cp source.txt backup.txt
|
||||
|
||||
# Copy to directory
|
||||
$ cp file.txt documents/
|
||||
|
||||
# Copy directory recursively
|
||||
$ cp -R project/ project_backup/
|
||||
|
||||
# Copy multiple files to directory
|
||||
$
|
||||
1249
web_src/05_Lectures/05_Metabarcoding/Biodiversity_indices/Slides.qmd
Normal file
@@ -0,0 +1,167 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 2031 2071" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:square;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-192,-982)">
|
||||
<g id="Main-Plot">
|
||||
<g>
|
||||
<g id="Grille">
|
||||
<g transform="matrix(1.1808,0,0,1,-75.4118,0)">
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,-172.262)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,975.279)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,811.344)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,647.41)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,1303.15)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,319.541)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,155.607)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,-8.32717)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,1139.21)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,483.476)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(3.34494e-16,1.1808,-1,2.83277e-16,3205.71,544.557)">
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,-172.262)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,975.279)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,811.344)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,647.41)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,1303.15)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,319.541)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,155.607)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,-8.32717)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,1139.21)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1.31073,-19.234,483.476)">
|
||||
<path d="M436.328,1027.97L1919.68,1027.97" style="fill:none;stroke-width:50.1px;stroke:rgb(181,181,181);"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Manhattan-distance">
|
||||
<g transform="matrix(1.01074,0,0,1.02216,-24.6851,-56.3204)">
|
||||
<clipPath id="_clip1">
|
||||
<path d="M1863.49,1501.96L718.479,1502.83L720.193,2321.91"/>
|
||||
</clipPath>
|
||||
<g clip-path="url(#_clip1)">
|
||||
<g transform="matrix(0.989373,0,0,0.978321,24.4228,55.0994)">
|
||||
<path d="M731.553,2320.07L1041.96,2321.26L1869.39,1502.84" style="fill:none;stroke-width:20.83px;stroke:rgb(239,159,75);"/>
|
||||
</g>
|
||||
</g>
|
||||
<path d="M1863.49,1501.96L718.479,1502.83L720.193,2321.91" style="fill:none;stroke-width:20.5px;stroke:rgb(239,159,75);"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-8.23449,-149.065)">
|
||||
<path d="M745.363,2464.19L745.61,1981.62L894.445,1981.51L893.831,1816.25L1221.66,1817.42L1222.61,1674.94L1870.55,1673.53" style="fill:none;stroke-width:20.83px;stroke:rgb(239,159,75);"/>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Euclidean-distance" transform="matrix(0.703395,-0.510486,0.510486,0.703395,-942.486,881.423)">
|
||||
<g transform="matrix(-1.21281,-1.91042e-15,-5.1683e-15,18.1142,3042.18,-42457.3)">
|
||||
<path d="M723.133,2480.78L2039.58,2480.04" style="fill:none;stroke-width:1.87px;stroke:rgb(31,146,28);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.73227,-8.453e-16,7.24543e-16,1.73227,700.347,-1893.39)">
|
||||
<text x="183.268px" y="2487.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Euclidean distance</text>
|
||||
</g>
|
||||
<g transform="matrix(1.40197,1.01747,-1.01747,1.40197,3635.4,-1896.41)">
|
||||
<text x="183.268px" y="2487.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Manhattan distance</text>
|
||||
</g>
|
||||
<g transform="matrix(1.70572,-0.302138,0.302138,1.70572,92.3532,-1423.68)">
|
||||
<text x="183.268px" y="2487.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Chebyshev distance</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-7.03869,-1.75967)">
|
||||
<path d="M1869.12,1514.53L1052.81,2325.83L741.235,2322.67" style="fill:none;stroke-width:20.83px;stroke-linecap:butt;stroke:rgb(201,0,157);"/>
|
||||
</g>
|
||||
<g id="Point-B" transform="matrix(1,0,0,1,330.868,1784.29)">
|
||||
<g transform="matrix(1,0,0,1,2.98908,0)">
|
||||
<ellipse cx="381.618" cy="545.025" rx="28.788" ry="32.295" style="fill:rgb(235,235,235);stroke-width:62.5px;stroke:rgb(0,19,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(2.92627,0,0,2.04123,-334.325,-1052.74)">
|
||||
<text x="229.007px" y="733.807px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">A</text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Point-B1" transform="matrix(1,0,0,1,1080.14,962.633)">
|
||||
<g transform="matrix(1,0,0,1,402.614,0)">
|
||||
<ellipse cx="381.618" cy="545.025" rx="28.788" ry="32.295" style="fill:rgb(235,235,235);stroke-width:62.5px;stroke:rgb(255,0,6);"/>
|
||||
</g>
|
||||
<g transform="matrix(2.92627,0,0,2.04123,65.3005,-1052.74)">
|
||||
<text x="229.007px" y="733.807px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">B</text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Coordinates">
|
||||
<g id="B">
|
||||
<g id="Xb">
|
||||
<g id="Xb1" transform="matrix(1.40046e-16,-2.28712,1,6.12323e-17,-458.914,3473.11)">
|
||||
<path d="M254.53,2321.59L898.365,2321.59" style="fill:none;stroke-width:5.9px;stroke-linecap:butt;stroke-dasharray:5.9,5.9,5.9,0;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(20.9725,0,1.97215e-31,20.9725,-12015.1,-59666.6)">
|
||||
<text x="658.77px" y="2988.33px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:6.548px;fill:black;">x</text>
|
||||
<text x="662.044px" y="2990.51px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:3.817px;fill:black;">B</text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Yb">
|
||||
<g id="Yb1" transform="matrix(2.53289,0,0,0.949467,-314.832,-697.08)">
|
||||
<path d="M254.53,2321.59L898.365,2321.59" style="fill:none;stroke-width:5.45px;stroke-linecap:butt;stroke-dasharray:5.45,5.45,5.45,0;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(20.9725,0,1.97215e-31,20.9725,-13626.2,-61124.7)">
|
||||
<text x="658.77px" y="2988.33px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:6.548px;fill:black;">y</text>
|
||||
<text x="662.044px" y="2990.51px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:3.817px;fill:black;">B</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g id="A">
|
||||
<g id="Ya">
|
||||
<g id="Ya1" transform="matrix(0.865442,-6.16298e-33,0,1,109.585,4.54747e-13)">
|
||||
<path d="M254.53,2321.59L898.365,2321.59" style="fill:none;stroke-width:11.14px;stroke-linecap:butt;stroke-dasharray:11.14,11.14,11.14,0;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(20.9725,0,0,20.9725,-13626.2,-60326.8)">
|
||||
<text x="658.77px" y="2988.33px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:6.548px;fill:black;">y</text>
|
||||
<text x="662.044px" y="2990.51px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:3.817px;fill:black;">A</text>
|
||||
</g>
|
||||
</g>
|
||||
<g id="Xa">
|
||||
<g id="Xa1" transform="matrix(6.08856e-17,-0.994338,1,6.12323e-17,-1605.05,3144.05)">
|
||||
<path d="M254.53,2321.59L898.365,2321.59" style="fill:black;stroke-width:10.45px;stroke-linecap:butt;stroke-dasharray:10.45,10.45,10.45,0;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(20.9725,0,0,20.9725,-13160.4,-59666.6)">
|
||||
<text x="658.77px" y="2988.33px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:6.548px;fill:black;">x</text>
|
||||
<text x="662.044px" y="2990.51px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:3.817px;fill:black;">A</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 12 KiB |
@@ -0,0 +1,108 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 2021 852" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-187,-683)">
|
||||
<g>
|
||||
<g>
|
||||
<g transform="matrix(0.824429,0,0,0.824429,40.8885,111.226)">
|
||||
<rect x="195.263" y="711.481" width="997.627" height="997.627" style="fill:rgb(235,235,235);stroke-width:20.22px;stroke:black;"/>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(1,0,0,1,324.539,-65.9235)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(248,0,230);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-62.3224,-805.515)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">B</text>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(82,110,255);"/>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-386.861,-739.592)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">A</text>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(1,0,0,1,291.652,223.089)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(109,255,87);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-97.6439,-516.503)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">D</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-17.2537,10.505)">
|
||||
<text x="245.684px" y="752.356px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Environment 1</text>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(1,0,0,1,-9.40327,285.266)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(255,255,49);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-398.699,-454.326)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">C</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(0.824429,0,0,0.824429,1209.24,111.226)">
|
||||
<rect x="195.263" y="711.481" width="997.627" height="997.627" style="fill:rgb(235,235,235);stroke-width:20.22px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.333632,0,0,0.333632,1745.99,939.675)">
|
||||
<g transform="matrix(1,0,0,1,324.539,-65.9235)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(80,254,255);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-62.3224,-805.515)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">G</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1165.64,10.505)">
|
||||
<text x="245.684px" y="752.356px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Environment 2</text>
|
||||
</g>
|
||||
<g transform="matrix(0.333632,0,0,0.333632,1563.39,529.401)">
|
||||
<g transform="matrix(1,0,0,1,324.539,-65.9235)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(248,0,230);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-62.3224,-805.515)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">B</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.333632,0,0,0.333632,1745.51,807.014)">
|
||||
<g transform="matrix(1,0,0,1,324.539,-65.9235)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(255,201,226);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-62.3224,-805.515)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">F</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.333632,0,0,0.333632,1711.84,590.465)">
|
||||
<g transform="matrix(1,0,0,1,324.539,-65.9235)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(255,95,111);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-62.3224,-805.515)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">E</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.74862,0,0,1.74862,827.639,-680.448)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(82,110,255);"/>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-386.861,-739.592)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">A</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.468295,0,0,0.468295,1493.29,758.779)">
|
||||
<g transform="matrix(1,0,0,1,291.652,223.089)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(109,255,87);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-97.6439,-516.503)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">D</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(0.311548,0,0,0.311548,1336.31,890.508)">
|
||||
<g transform="matrix(1,0,0,1,-9.40327,285.266)">
|
||||
<ellipse cx="477.16" cy="995.163" rx="110.023" ry="109.093" style="fill:rgb(255,255,49);"/>
|
||||
</g>
|
||||
<g transform="matrix(1.76539,0,0,1.76539,-398.699,-454.326)">
|
||||
<text x="472.748px" y="995.259px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">C</text>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.1 KiB |
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1846 1637" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-105,-316)">
|
||||
<g>
|
||||
<g>
|
||||
<g transform="matrix(3.56657,0,0,3.42572,-1715.29,-1858.59)">
|
||||
<ellipse cx="815.464" cy="910.747" rx="208.192" ry="186.092" style="fill:rgb(235,235,235);stroke-width:4.77px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.37512,0,0,2.37512,-1050.26,-4483.8)">
|
||||
<text x="805.445px" y="2617.15px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Environment</text>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(0.875323,0,0,0.814584,53.5525,-933.789)">
|
||||
<ellipse cx="826.904" cy="2457.22" rx="238.262" ry="246.522" style="fill:rgb(142,255,140);stroke-width:19.71px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.01739,0,0,2.01739,-329.967,-4026.53)">
|
||||
<text x="483.571px" y="2537.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Site <tspan x="580.861px " y="2537.83px ">A</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(0.875323,0,0,0.814584,495.154,-585.114)">
|
||||
<ellipse cx="826.904" cy="2457.22" rx="238.262" ry="246.522" style="fill:rgb(255,178,148);stroke-width:19.71px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.01739,0,0,2.01739,126.222,-3672.28)">
|
||||
<text x="483.571px" y="2537.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Site B</text>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="matrix(0.875323,0,0,0.814584,875.962,-933.789)">
|
||||
<ellipse cx="826.904" cy="2457.22" rx="238.262" ry="246.522" style="fill:rgb(252,255,142);stroke-width:19.71px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.01739,0,0,2.01739,486.877,-4026.53)">
|
||||
<text x="483.571px" y="2537.83px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">Site C</text>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(1.90555,0,0,1.90555,-1159.48,-204.501)">
|
||||
<text x="1107.37px" y="318.159px" style="font-family:'STIXGeneral-Regular', 'STIXGeneral';font-size:65.598px;fill:black;">𝛂-div<tspan x="1253.72px " y="318.159px ">e</tspan>rsity</text>
|
||||
</g>
|
||||
<g transform="matrix(1.90555,0,0,1.90555,-2008.56,1318.74)">
|
||||
<text x="1107.37px" y="318.159px" style="font-family:'STIXGeneral-Italic', 'STIXGeneral';font-style:italic;font-size:65.598px;fill:black;">𝛾</text>
|
||||
<text x="1135.45px" y="318.159px" style="font-family:'STIXGeneral-Regular', 'STIXGeneral';font-size:65.598px;fill:black;">-div<tspan x="1239.55px " y="318.159px ">e</tspan>rsity</text>
|
||||
</g>
|
||||
<g transform="matrix(1.90555,0,0,1.90555,-1535.83,762.329)">
|
||||
<text x="1107.37px" y="318.159px" style="font-family:'STIXGeneral-Italic', 'STIXGeneral';font-style:italic;font-size:50px;fill:black;">𝛽</text>
|
||||
<text x="1132.02px" y="318.159px" style="font-family:'STIXGeneral-Regular', 'STIXGeneral';font-size:50px;fill:black;">-div<tspan x="1211.37px " y="318.159px ">e</tspan>rsity</text>
|
||||
</g>
|
||||
<g transform="matrix(-2.57949e-16,1.40421,-7.56783,-1.39019e-15,3559.03,56.614)">
|
||||
<path d="M287.175,308.403L287.175,306.419L860.49,306.419L860.49,303.444L913.72,307.411L860.49,311.379L860.49,308.403L287.175,308.403Z" style="fill:black;stroke-width:0.69px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(-0.612613,0.844268,-6.71099,-4.86959,3409.58,1712.57)">
|
||||
<path d="M287.175,308.403L287.175,306.419L835.211,306.419L835.211,303.444L913.72,307.411L835.211,311.379L835.211,308.403L287.175,308.403Z" style="fill:black;stroke-width:0.63px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.251261,-0.311578,5.89101,4.75059,-1333.11,417.689)">
|
||||
<path d="M287.175,308.403L287.175,306.419L726.98,306.419L726.98,303.444L913.72,307.411L726.98,311.379L726.98,308.403L287.175,308.403Z" style="fill:black;stroke-width:0.7px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.437815,0.363403,-4.83348,5.8232,2225.37,-773.088)">
|
||||
<path d="M418.542,308.403L418.542,311.379L287.175,307.411L418.542,303.444L418.542,306.419L782.353,306.419L782.353,303.444L913.72,307.411L782.353,311.379L782.353,308.403L418.542,308.403Z" style="fill:black;stroke-width:0.7px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(0.345195,0.841982,-6.44148,2.64087,3196.59,-594.14)">
|
||||
<path d="M287.175,308.403L287.175,306.419L838.159,306.419L838.159,303.444L913.72,307.411L838.159,311.379L838.159,308.403L287.175,308.403Z" style="fill:black;stroke-width:0.76px;stroke:black;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
@@ -0,0 +1,34 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1502 1501" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-380,-775)">
|
||||
<g transform="matrix(1,0,0,1.48478,0,-917.84)">
|
||||
<path d="M775.395,1921.11L775.395,1913.9L1685.12,1913.9L1685.12,1893.32L1756.93,1917.5L1685.12,1941.69L1685.12,1921.11L775.395,1921.11Z" style="fill:rgb(0,1,2);"/>
|
||||
</g>
|
||||
<g transform="matrix(0.605804,-0.795614,1.18131,0.899484,-1951.37,817.912)">
|
||||
<path d="M775.395,1921.11L775.395,1913.9L1685.12,1913.9L1685.12,1893.32L1756.93,1917.5L1685.12,1941.69L1685.12,1921.11L775.395,1921.11Z" style="fill:rgb(0,1,2);"/>
|
||||
</g>
|
||||
<g transform="matrix(3.8068,0,0,3.89337,-3178.36,-6714.08)">
|
||||
<circle cx="1035.39" cy="2222.51" r="260.137" style="fill:none;stroke-width:0.87px;stroke-dasharray:0.87,3.46,0.87,0;stroke:black;"/>
|
||||
</g>
|
||||
<path d="M2051.47,1936.49L526.666,1926.49" style="fill:none;stroke-width:3.33px;stroke-dasharray:3.33,13.33,3.33,0;stroke:black;"/>
|
||||
<g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-1146.44,2711.11)">
|
||||
<path d="M2051.47,1936.49L526.666,1926.49" style="fill:none;stroke-width:3.33px;stroke-dasharray:3.33,13.33,3.33,0;stroke:black;"/>
|
||||
</g>
|
||||
<path d="M1378.06,1143.23L1754.19,1928.24" style="fill:none;stroke-width:8.33px;stroke:rgb(253,36,0);"/>
|
||||
<g transform="matrix(6.12323e-17,-1,1,6.12323e-17,-359.004,3304.88)">
|
||||
<path d="M1378.06,1143.23L1754.19,1928.24" style="fill:none;stroke-width:8.33px;stroke-dasharray:8.33,33.33,8.33,0;stroke:rgb(253,36,0);"/>
|
||||
</g>
|
||||
<g transform="matrix(-3.81475e-16,-2.37218,2.37218,-3.81475e-16,-3006.71,2967.43)">
|
||||
<path d="M437.279,1709.62C472.759,1709.62 506.172,1692.93 527.486,1664.57L437.279,1596.78L437.279,1709.62Z" style="fill:none;stroke-width:3.51px;stroke-dasharray:3.51,14.05,3.51,0;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,-11.9118,184.176)">
|
||||
<text x="1089.21px" y="1669.29px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">cos(</text>
|
||||
<text x="1183.67px" y="1669.29px" style="font-family:'STIXGeneral-Regular', 'STIXGeneral';font-size:50px;fill:black;">𝛼</text>
|
||||
<text x="1209.87px" y="1669.29px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">)=R</text>
|
||||
</g>
|
||||
<g transform="matrix(2.44125,0,0,1.95351,-2681.3,-1267.15)">
|
||||
<text x="1776.48px" y="1492.45px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:rgb(255,76,31);">d</text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1267 936" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-473,-887)">
|
||||
<g id="metric" transform="matrix(1,0,0,1,85.1006,-84.2667)">
|
||||
<g transform="matrix(1,0,0,1,0.196399,0)">
|
||||
<path d="M520.389,1821.09L1554.35,1821.09" style="fill:none;stroke-width:1px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(6.12323e-17,-1,-1,-6.12323e-17,2858.39,2245.09)">
|
||||
<path d="M1137.81,2034.33L423.607,2337.94L423.239,1303.71L1137.81,2034.33Z" style="fill:none;stroke-width:1px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-1742.45,-175.128)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">C</text>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-2137.03,670.818)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">A</text>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-946.651,670.818)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">B</text>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,19.4596,34.2956)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1044.28,33.9027)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,319.278,-679.347)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.2 KiB |
|
After Width: | Height: | Size: 408 KiB |
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<svg width="100%" height="100%" viewBox="0 0 1267 1445" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xml:space="preserve" style="fill-rule:evenodd;clip-rule:evenodd;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:1.41421;">
|
||||
<g transform="matrix(1,0,0,1,-388,-463)">
|
||||
<g id="Umtrametric">
|
||||
<g transform="matrix(1,0,0,1,0.196399,0)">
|
||||
<path d="M520.389,1821.09L1554.35,1821.09" style="fill:none;stroke-width:1px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(6.12323e-17,-1,-1,-6.12323e-17,2858.39,2245.09)">
|
||||
<path d="M1554.35,1821.09L423.607,2337.94L423.239,1303.71L1554.31,1821" style="fill:none;stroke-width:1px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-1532.55,-683.049)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">C</text>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-2137.03,670.818)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">A</text>
|
||||
</g>
|
||||
<g transform="matrix(2.46916,0,0,2.46916,-946.651,670.818)">
|
||||
<text x="1022.83px" y="500.74px" style="font-family:'ArialMT', 'Arial', sans-serif;font-size:50px;fill:black;">B</text>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,19.4596,34.2956)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,1044.28,33.9027)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
<g transform="matrix(1,0,0,1,529.835,-1093.64)">
|
||||
<circle cx="505.904" cy="1785.24" r="15.508" style="fill:rgb(255,120,60);stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M740.104,1216.22L832.267,1257.12" style="fill:none;stroke-width:3.33px;stroke:black;"/>
|
||||
<g transform="matrix(1,0,0,1,7,-17)">
|
||||
<path d="M740.104,1216.22L832.267,1257.12" style="fill:none;stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
</g>
|
||||
<g transform="matrix(-1,0,0,1,2071.79,-0.155385)">
|
||||
<path d="M740.104,1216.22L832.267,1257.12" style="fill:none;stroke-width:3.33px;stroke:black;"/>
|
||||
<g transform="matrix(1,0,0,1,7,-17)">
|
||||
<path d="M740.104,1216.22L832.267,1257.12" style="fill:none;stroke-width:3.33px;stroke:black;"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
@@ -0,0 +1,60 @@
|
||||
%% This BibTeX bibliography file was created using BibDesk.
|
||||
%% http://bibdesk.sourceforge.net/
|
||||
|
||||
|
||||
%% Created for Eric Coissac at 2018-10-18 14:52:51 +0200
|
||||
|
||||
|
||||
%% Saved with string encoding Unicode (UTF-8)
|
||||
|
||||
|
||||
|
||||
@article{Tsallis:94:00,
|
||||
Author = {Tsallis, Constantino},
|
||||
Date-Added = {2018-10-18 14:52:41 +0200},
|
||||
Date-Modified = {2018-10-18 14:52:49 +0200},
|
||||
Journal = {Quim. Nova},
|
||||
Number = 6,
|
||||
Pages = {468--471},
|
||||
Title = {What are the numbers that experiments provide},
|
||||
Volume = 17,
|
||||
Year = 1994}
|
||||
|
||||
|
||||
@ARTICLE{Whittaker:10:00,
|
||||
title = "Meta-analyses and mega-mistakes: calling time on meta-analysis
|
||||
of the species richness-productivity relationship",
|
||||
author = "Whittaker, Robert J",
|
||||
abstract = "The form of the species richness-productivity relationship
|
||||
(SRPR) is both theoretically important and contentious. In an
|
||||
effort to distill general patterns, ecologists have undertaken
|
||||
meta-analyses, within which each SRPR data set is first
|
||||
classified into one of five alternative forms: positive, humped
|
||||
(unimodal), negative, U-shaped (unimodal), and no relationship.
|
||||
Herein, I first provide a critique of this approach, based on 68
|
||||
plant data sets/ studies used in three meta-analyses published
|
||||
in Ecology. The meta-analyses are shown to have resulted in
|
||||
highly divergent outcomes, inconsistent and often highly
|
||||
inappropriate classification of data sets, and the introduction
|
||||
and multiplication of errors from one meta-analysis to the next.
|
||||
I therefore call on the ecological community at large to adopt a
|
||||
far more rigorous and critical attitude to the use of
|
||||
meta-analysis. Second, I develop the argument that the
|
||||
literature on the SRPR continues to be bedeviled by a common
|
||||
failing to appreciate the fundamental importance of the scale of
|
||||
analysis, beginning with the confusion evident between concepts
|
||||
of grain, focus, and extent. I postulate that variation in the
|
||||
form of the SRPR at fine scales of analysis owes much to
|
||||
artifacts of the sampling regime adopted. An improved
|
||||
understanding may emerge from combining sampling theory with an
|
||||
understanding of the factors controlling the form of species
|
||||
abundance distributions and species accumulation curves.",
|
||||
journal = "Ecology",
|
||||
publisher = "Eco Soc America",
|
||||
volume = 91,
|
||||
number = 9,
|
||||
pages = "2522--2533",
|
||||
month = sep,
|
||||
year = 2010
|
||||
}
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
/* Centre toutes les images dans les slides */
|
||||
|
||||
.reveal {
|
||||
font-size: 1.5em;
|
||||
}
|
||||
|
||||
.quarto-figure-default {
|
||||
display: block;
|
||||
margin-left: auto;
|
||||