From 50e6d15fff791930cfe43c60fb55f5f55b385fb6 Mon Sep 17 00:00:00 2001
From: Victor Dudochkin <dudochkin.victor@gmail.com>
Date: Mon, 29 Mar 2021 21:24:41 +0700
Subject: [PATCH 1/4] Push docs

---
 .github/workflows/publish_gh_pages.yml |  30 ++
 .gitignore                             |   5 +
 LICENSE                                | 373 ++++++++++++++
 README.md                              |   1 +
 book.toml                              |  10 +
 src/SUMMARY.md                         |   3 +
 src/chapter_1.md                       |   1 +
 src/theme/book.js                      | 660 +++++++++++++++++++++++++
 src/theme/css/chrome.css               | 495 +++++++++++++++++++
 src/theme/css/general.css              | 174 +++++++
 src/theme/css/print.css                |  54 ++
 src/theme/css/variables.css            | 253 ++++++++++
 src/theme/favicon.png                  | Bin 0 -> 5679 bytes
 src/theme/favicon.svg                  |  22 +
 src/theme/highlight.css                |  79 +++
 src/theme/highlight.js                 |   6 +
 src/theme/index.hbs                    | 306 ++++++++++++
 17 files changed, 2472 insertions(+)
 create mode 100644 .github/workflows/publish_gh_pages.yml
 create mode 100644 .gitignore
 create mode 100644 LICENSE
 create mode 100644 README.md
 create mode 100644 book.toml
 create mode 100644 src/SUMMARY.md
 create mode 100644 src/chapter_1.md
 create mode 100644 src/theme/book.js
 create mode 100644 src/theme/css/chrome.css
 create mode 100644 src/theme/css/general.css
 create mode 100644 src/theme/css/print.css
 create mode 100644 src/theme/css/variables.css
 create mode 100644 src/theme/favicon.png
 create mode 100644 src/theme/favicon.svg
 create mode 100644 src/theme/highlight.css
 create mode 100644 src/theme/highlight.js
 create mode 100644 src/theme/index.hbs

diff --git a/.github/workflows/publish_gh_pages.yml b/.github/workflows/publish_gh_pages.yml
new file mode 100644
index 0000000..f1d443d
--- /dev/null
+++ b/.github/workflows/publish_gh_pages.yml
@@ -0,0 +1,30 @@
+# This is a basic workflow to help you get started with Actions
+
+# On every push this script is executed
+
+name: github pages
+
+on:
+  push:
+    branches:
+      - pages
+
+jobs:
+  deploy:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+
+      - name: Setup mdBook
+        uses: peaceiris/actions-mdbook@v1
+        with:
+          mdbook-version: '0.4.6'
+          # mdbook-version: 'latest'
+
+      - run: mdbook build
+
+      - name: Deploy
+        uses: peaceiris/actions-gh-pages@v3
+        with:
+          github_token: ${{ secrets.TOKEN }}
+          publish_dir: ./book
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..3597896
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
+.idea
+.vscode
+.DS_Store
+/public/
+/book/
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..a612ad9
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,373 @@
+Mozilla Public License Version 2.0
+==================================
+
+1. Definitions
+--------------
+
+1.1. "Contributor"
+    means each individual or legal entity that creates, contributes to
+    the creation of, or owns Covered Software.
+
+1.2. "Contributor Version"
+    means the combination of the Contributions of others (if any) used
+    by a Contributor and that particular Contributor's Contribution.
+
+1.3. "Contribution"
+    means Covered Software of a particular Contributor.
+
+1.4. "Covered Software"
+    means Source Code Form to which the initial Contributor has attached
+    the notice in Exhibit A, the Executable Form of such Source Code
+    Form, and Modifications of such Source Code Form, in each case
+    including portions thereof.
+
+1.5. "Incompatible With Secondary Licenses"
+    means
+
+    (a) that the initial Contributor has attached the notice described
+        in Exhibit B to the Covered Software; or
+
+    (b) that the Covered Software was made available under the terms of
+        version 1.1 or earlier of the License, but not also under the
+        terms of a Secondary License.
+
+1.6. "Executable Form"
+    means any form of the work other than Source Code Form.
+
+1.7. "Larger Work"
+    means a work that combines Covered Software with other material, in
+    a separate file or files, that is not Covered Software.
+
+1.8. "License"
+    means this document.
+
+1.9. "Licensable"
+    means having the right to grant, to the maximum extent possible,
+    whether at the time of the initial grant or subsequently, any and
+    all of the rights conveyed by this License.
+
+1.10. "Modifications"
+    means any of the following:
+
+    (a) any file in Source Code Form that results from an addition to,
+        deletion from, or modification of the contents of Covered
+        Software; or
+
+    (b) any new file in Source Code Form that contains any Covered
+        Software.
+
+1.11. "Patent Claims" of a Contributor
+    means any patent claim(s), including without limitation, method,
+    process, and apparatus claims, in any patent Licensable by such
+    Contributor that would be infringed, but for the grant of the
+    License, by the making, using, selling, offering for sale, having
+    made, import, or transfer of either its Contributions or its
+    Contributor Version.
+
+1.12. "Secondary License"
+    means either the GNU General Public License, Version 2.0, the GNU
+    Lesser General Public License, Version 2.1, the GNU Affero General
+    Public License, Version 3.0, or any later versions of those
+    licenses.
+
+1.13. "Source Code Form"
+    means the form of the work preferred for making modifications.
+
+1.14. "You" (or "Your")
+    means an individual or a legal entity exercising rights under this
+    License. For legal entities, "You" includes any entity that
+    controls, is controlled by, or is under common control with You. For
+    purposes of this definition, "control" means (a) the power, direct
+    or indirect, to cause the direction or management of such entity,
+    whether by contract or otherwise, or (b) ownership of more than
+    fifty percent (50%) of the outstanding shares or beneficial
+    ownership of such entity.
+
+2. License Grants and Conditions
+--------------------------------
+
+2.1. Grants
+
+Each Contributor hereby grants You a world-wide, royalty-free,
+non-exclusive license:
+
+(a) under intellectual property rights (other than patent or trademark)
+    Licensable by such Contributor to use, reproduce, make available,
+    modify, display, perform, distribute, and otherwise exploit its
+    Contributions, either on an unmodified basis, with Modifications, or
+    as part of a Larger Work; and
+
+(b) under Patent Claims of such Contributor to make, use, sell, offer
+    for sale, have made, import, and otherwise transfer either its
+    Contributions or its Contributor Version.
+
+2.2. Effective Date
+
+The licenses granted in Section 2.1 with respect to any Contribution
+become effective for each Contribution on the date the Contributor first
+distributes such Contribution.
+
+2.3. Limitations on Grant Scope
+
+The licenses granted in this Section 2 are the only rights granted under
+this License. No additional rights or licenses will be implied from the
+distribution or licensing of Covered Software under this License.
+Notwithstanding Section 2.1(b) above, no patent license is granted by a
+Contributor:
+
+(a) for any code that a Contributor has removed from Covered Software;
+    or
+
+(b) for infringements caused by: (i) Your and any other third party's
+    modifications of Covered Software, or (ii) the combination of its
+    Contributions with other software (except as part of its Contributor
+    Version); or
+
+(c) under Patent Claims infringed by Covered Software in the absence of
+    its Contributions.
+
+This License does not grant any rights in the trademarks, service marks,
+or logos of any Contributor (except as may be necessary to comply with
+the notice requirements in Section 3.4).
+
+2.4. Subsequent Licenses
+
+No Contributor makes additional grants as a result of Your choice to
+distribute the Covered Software under a subsequent version of this
+License (see Section 10.2) or under the terms of a Secondary License (if
+permitted under the terms of Section 3.3).
+
+2.5. Representation
+
+Each Contributor represents that the Contributor believes its
+Contributions are its original creation(s) or it has sufficient rights
+to grant the rights to its Contributions conveyed by this License.
+
+2.6. Fair Use
+
+This License is not intended to limit any rights You have under
+applicable copyright doctrines of fair use, fair dealing, or other
+equivalents.
+
+2.7. Conditions
+
+Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted
+in Section 2.1.
+
+3. Responsibilities
+-------------------
+
+3.1. Distribution of Source Form
+
+All distribution of Covered Software in Source Code Form, including any
+Modifications that You create or to which You contribute, must be under
+the terms of this License. You must inform recipients that the Source
+Code Form of the Covered Software is governed by the terms of this
+License, and how they can obtain a copy of this License. You may not
+attempt to alter or restrict the recipients' rights in the Source Code
+Form.
+
+3.2. Distribution of Executable Form
+
+If You distribute Covered Software in Executable Form then:
+
+(a) such Covered Software must also be made available in Source Code
+    Form, as described in Section 3.1, and You must inform recipients of
+    the Executable Form how they can obtain a copy of such Source Code
+    Form by reasonable means in a timely manner, at a charge no more
+    than the cost of distribution to the recipient; and
+
+(b) You may distribute such Executable Form under the terms of this
+    License, or sublicense it under different terms, provided that the
+    license for the Executable Form does not attempt to limit or alter
+    the recipients' rights in the Source Code Form under this License.
+
+3.3. Distribution of a Larger Work
+
+You may create and distribute a Larger Work under terms of Your choice,
+provided that You also comply with the requirements of this License for
+the Covered Software. If the Larger Work is a combination of Covered
+Software with a work governed by one or more Secondary Licenses, and the
+Covered Software is not Incompatible With Secondary Licenses, this
+License permits You to additionally distribute such Covered Software
+under the terms of such Secondary License(s), so that the recipient of
+the Larger Work may, at their option, further distribute the Covered
+Software under the terms of either this License or such Secondary
+License(s).
+
+3.4. Notices
+
+You may not remove or alter the substance of any license notices
+(including copyright notices, patent notices, disclaimers of warranty,
+or limitations of liability) contained within the Source Code Form of
+the Covered Software, except that You may alter any license notices to
+the extent required to remedy known factual inaccuracies.
+
+3.5. Application of Additional Terms
+
+You may choose to offer, and to charge a fee for, warranty, support,
+indemnity or liability obligations to one or more recipients of Covered
+Software. However, You may do so only on Your own behalf, and not on
+behalf of any Contributor. You must make it absolutely clear that any
+such warranty, support, indemnity, or liability obligation is offered by
+You alone, and You hereby agree to indemnify every Contributor for any
+liability incurred by such Contributor as a result of warranty, support,
+indemnity or liability terms You offer. You may include additional
+disclaimers of warranty and limitations of liability specific to any
+jurisdiction.
+
+4. Inability to Comply Due to Statute or Regulation
+---------------------------------------------------
+
+If it is impossible for You to comply with any of the terms of this
+License with respect to some or all of the Covered Software due to
+statute, judicial order, or regulation then You must: (a) comply with
+the terms of this License to the maximum extent possible; and (b)
+describe the limitations and the code they affect. Such description must
+be placed in a text file included with all distributions of the Covered
+Software under this License. Except to the extent prohibited by statute
+or regulation, such description must be sufficiently detailed for a
+recipient of ordinary skill to be able to understand it.
+
+5. Termination
+--------------
+
+5.1. The rights granted under this License will terminate automatically
+if You fail to comply with any of its terms. However, if You become
+compliant, then the rights granted under this License from a particular
+Contributor are reinstated (a) provisionally, unless and until such
+Contributor explicitly and finally terminates Your grants, and (b) on an
+ongoing basis, if such Contributor fails to notify You of the
+non-compliance by some reasonable means prior to 60 days after You have
+come back into compliance. Moreover, Your grants from a particular
+Contributor are reinstated on an ongoing basis if such Contributor
+notifies You of the non-compliance by some reasonable means, this is the
+first time You have received notice of non-compliance with this License
+from such Contributor, and You become compliant prior to 30 days after
+Your receipt of the notice.
+
+5.2. If You initiate litigation against any entity by asserting a patent
+infringement claim (excluding declaratory judgment actions,
+counter-claims, and cross-claims) alleging that a Contributor Version
+directly or indirectly infringes any patent, then the rights granted to
+You by any and all Contributors for the Covered Software under Section
+2.1 of this License shall terminate.
+
+5.3. In the event of termination under Sections 5.1 or 5.2 above, all
+end user license agreements (excluding distributors and resellers) which
+have been validly granted by You or Your distributors under this License
+prior to termination shall survive termination.
+
+************************************************************************
+*                                                                      *
+*  6. Disclaimer of Warranty                                           *
+*  -------------------------                                           *
+*                                                                      *
+*  Covered Software is provided under this License on an "as is"       *
+*  basis, without warranty of any kind, either expressed, implied, or  *
+*  statutory, including, without limitation, warranties that the       *
+*  Covered Software is free of defects, merchantable, fit for a        *
+*  particular purpose or non-infringing. The entire risk as to the     *
+*  quality and performance of the Covered Software is with You.        *
+*  Should any Covered Software prove defective in any respect, You     *
+*  (not any Contributor) assume the cost of any necessary servicing,   *
+*  repair, or correction. This disclaimer of warranty constitutes an   *
+*  essential part of this License. No use of any Covered Software is   *
+*  authorized under this License except under this disclaimer.         *
+*                                                                      *
+************************************************************************
+
+************************************************************************
+*                                                                      *
+*  7. Limitation of Liability                                          *
+*  --------------------------                                          *
+*                                                                      *
+*  Under no circumstances and under no legal theory, whether tort      *
+*  (including negligence), contract, or otherwise, shall any           *
+*  Contributor, or anyone who distributes Covered Software as          *
+*  permitted above, be liable to You for any direct, indirect,         *
+*  special, incidental, or consequential damages of any character      *
+*  including, without limitation, damages for lost profits, loss of    *
+*  goodwill, work stoppage, computer failure or malfunction, or any    *
+*  and all other commercial damages or losses, even if such party      *
+*  shall have been informed of the possibility of such damages. This   *
+*  limitation of liability shall not apply to liability for death or   *
+*  personal injury resulting from such party's negligence to the       *
+*  extent applicable law prohibits such limitation. Some               *
+*  jurisdictions do not allow the exclusion or limitation of           *
+*  incidental or consequential damages, so this exclusion and          *
+*  limitation may not apply to You.                                    *
+*                                                                      *
+************************************************************************
+
+8. Litigation
+-------------
+
+Any litigation relating to this License may be brought only in the
+courts of a jurisdiction where the defendant maintains its principal
+place of business and such litigation shall be governed by laws of that
+jurisdiction, without reference to its conflict-of-law provisions.
+Nothing in this Section shall prevent a party's ability to bring
+cross-claims or counter-claims.
+
+9. Miscellaneous
+----------------
+
+This License represents the complete agreement concerning the subject
+matter hereof. If any provision of this License is held to be
+unenforceable, such provision shall be reformed only to the extent
+necessary to make it enforceable. Any law or regulation which provides
+that the language of a contract shall be construed against the drafter
+shall not be used to construe this License against a Contributor.
+
+10. Versions of the License
+---------------------------
+
+10.1. New Versions
+
+Mozilla Foundation is the license steward. Except as provided in Section
+10.3, no one other than the license steward has the right to modify or
+publish new versions of this License. Each version will be given a
+distinguishing version number.
+
+10.2. Effect of New Versions
+
+You may distribute the Covered Software under the terms of the version
+of the License under which You originally received the Covered Software,
+or under the terms of any subsequent version published by the license
+steward.
+
+10.3. Modified Versions
+
+If you create software not governed by this License, and you want to
+create a new license for such software, you may create and use a
+modified version of this License if you rename the license and remove
+any references to the name of the license steward (except to note that
+such modified license differs from this License).
+
+10.4. Distributing Source Code Form that is Incompatible With Secondary
+Licenses
+
+If You choose to distribute Source Code Form that is Incompatible With
+Secondary Licenses under the terms of this version of the License, the
+notice described in Exhibit B of this License must be attached.
+
+Exhibit A - Source Code Form License Notice
+-------------------------------------------
+
+  This Source Code Form is subject to the terms of the Mozilla Public
+  License, v. 2.0. If a copy of the MPL was not distributed with this
+  file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+If it is not possible or desirable to put the notice in a particular
+file, then You may include the notice in a location (such as a LICENSE
+file in a relevant directory) where a recipient would be likely to look
+for such a notice.
+
+You may add additional accurate notices of copyright ownership.
+
+Exhibit B - "Incompatible With Secondary Licenses" Notice
+---------------------------------------------------------
+
+  This Source Code Form is "Incompatible With Secondary Licenses", as
+  defined by the Mozilla Public License, v. 2.0.
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..fb0a8d2
--- /dev/null
+++ b/README.md
@@ -0,0 +1 @@
+# mdbook-testing
\ No newline at end of file
diff --git a/book.toml b/book.toml
new file mode 100644
index 0000000..75c36ad
--- /dev/null
+++ b/book.toml
@@ -0,0 +1,10 @@
+[book]
+title = "UX Animate"
+authors = ["Victor Dudochkin"]
+language = "en"
+multilingual = false
+src = "src"
+
+[output.html]
+theme = "src/theme"
+site-url = "/ux-animate/"
diff --git a/src/SUMMARY.md b/src/SUMMARY.md
new file mode 100644
index 0000000..7390c82
--- /dev/null
+++ b/src/SUMMARY.md
@@ -0,0 +1,3 @@
+# Summary
+
+- [Chapter 1](./chapter_1.md)
diff --git a/src/chapter_1.md b/src/chapter_1.md
new file mode 100644
index 0000000..b743fda
--- /dev/null
+++ b/src/chapter_1.md
@@ -0,0 +1 @@
+# Chapter 1
diff --git a/src/theme/book.js b/src/theme/book.js
new file mode 100644
index 0000000..5e38636
--- /dev/null
+++ b/src/theme/book.js
@@ -0,0 +1,660 @@
+"use strict";
+
+// Fix back button cache problem
+window.onunload = function () { };
+
+// Global variable, shared between modules
+function playground_text(playground) {
+    let code_block = playground.querySelector("code");
+
+    if (window.ace && code_block.classList.contains("editable")) {
+        let editor = window.ace.edit(code_block);
+        return editor.getValue();
+    } else {
+        return code_block.textContent;
+    }
+}
+
+(function codeSnippets() {
+    function fetch_with_timeout(url, options, timeout = 6000) {
+        return Promise.race([
+            fetch(url, options),
+            new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout))
+        ]);
+    }
+
+    var playgrounds = Array.from(document.querySelectorAll(".playground"));
+    if (playgrounds.length > 0) {
+        fetch_with_timeout("https://play.rust-lang.org/meta/crates", {
+            headers: {
+                'Content-Type': "application/json",
+            },
+            method: 'POST',
+            mode: 'cors',
+        })
+        .then(response => response.json())
+        .then(response => {
+            // get list of crates available in the rust playground
+            let playground_crates = response.crates.map(item => item["id"]);
+            playgrounds.forEach(block => handle_crate_list_update(block, playground_crates));
+        });
+    }
+
+    function handle_crate_list_update(playground_block, playground_crates) {
+        // update the play buttons after receiving the response
+        update_play_button(playground_block, playground_crates);
+
+        // and install on change listener to dynamically update ACE editors
+        if (window.ace) {
+            let code_block = playground_block.querySelector("code");
+            if (code_block.classList.contains("editable")) {
+                let editor = window.ace.edit(code_block);
+                editor.addEventListener("change", function (e) {
+                    update_play_button(playground_block, playground_crates);
+                });
+                // add Ctrl-Enter command to execute rust code
+                editor.commands.addCommand({
+                    name: "run",
+                    bindKey: {
+                        win: "Ctrl-Enter",
+                        mac: "Ctrl-Enter"
+                    },
+                    exec: _editor => run_rust_code(playground_block)
+                });
+            }
+        }
+    }
+
+    // updates the visibility of play button based on `no_run` class and
+    // used crates vs ones available on http://play.rust-lang.org
+    function update_play_button(pre_block, playground_crates) {
+        var play_button = pre_block.querySelector(".play-button");
+
+        // skip if code is `no_run`
+        if (pre_block.querySelector('code').classList.contains("no_run")) {
+            play_button.classList.add("hidden");
+            return;
+        }
+
+        // get list of `extern crate`'s from snippet
+        var txt = playground_text(pre_block);
+        var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g;
+        var snippet_crates = [];
+        var item;
+        while (item = re.exec(txt)) {
+            snippet_crates.push(item[1]);
+        }
+
+        // check if all used crates are available on play.rust-lang.org
+        var all_available = snippet_crates.every(function (elem) {
+            return playground_crates.indexOf(elem) > -1;
+        });
+
+        if (all_available) {
+            play_button.classList.remove("hidden");
+        } else {
+            play_button.classList.add("hidden");
+        }
+    }
+
+    function run_rust_code(code_block) {
+        var result_block = code_block.querySelector(".result");
+        if (!result_block) {
+            result_block = document.createElement('code');
+            result_block.className = 'result hljs language-bash';
+
+            code_block.append(result_block);
+        }
+
+        let text = playground_text(code_block);
+        let classes = code_block.querySelector('code').classList;
+        let has_2018 = classes.contains("edition2018");
+        let edition = has_2018 ? "2018" : "2015";
+
+        var params = {
+            version: "stable",
+            optimize: "0",
+            code: text,
+            edition: edition
+        };
+
+        if (text.indexOf("#![feature") !== -1) {
+            params.version = "nightly";
+        }
+
+        result_block.innerText = "Running...";
+
+        fetch_with_timeout("https://play.rust-lang.org/evaluate.json", {
+            headers: {
+                'Content-Type': "application/json",
+            },
+            method: 'POST',
+            mode: 'cors',
+            body: JSON.stringify(params)
+        })
+        .then(response => response.json())
+        .then(response => result_block.innerText = response.result)
+        .catch(error => result_block.innerText = "Playground Communication: " + error.message);
+    }
+
+    // Syntax highlighting Configuration
+    hljs.configure({
+        tabReplace: '    ', // 4 spaces
+        languages: [],      // Languages used for auto-detection
+    });
+
+    let code_nodes = Array
+        .from(document.querySelectorAll('code'))
+        // Don't highlight `inline code` blocks in headers.
+        .filter(function (node) {return !node.parentElement.classList.contains("header"); });
+
+    if (window.ace) {
+        // language-rust class needs to be removed for editable
+        // blocks or highlightjs will capture events
+        Array
+            .from(document.querySelectorAll('code.editable'))
+            .forEach(function (block) { block.classList.remove('language-rust'); });
+
+        Array
+            .from(document.querySelectorAll('code:not(.editable)'))
+            .forEach(function (block) { hljs.highlightBlock(block); });
+    } else {
+        code_nodes.forEach(function (block) { hljs.highlightBlock(block); });
+    }
+
+    // Adding the hljs class gives code blocks the color css
+    // even if highlighting doesn't apply
+    code_nodes.forEach(function (block) { block.classList.add('hljs'); });
+
+    Array.from(document.querySelectorAll("code.language-rust")).forEach(function (block) {
+
+        var lines = Array.from(block.querySelectorAll('.boring'));
+        // If no lines were hidden, return
+        if (!lines.length) { return; }
+        block.classList.add("hide-boring");
+
+        var buttons = document.createElement('div');
+        buttons.className = 'buttons';
+        buttons.innerHTML = "<button class=\"fa fa-eye\" title=\"Show hidden lines\" aria-label=\"Show hidden lines\"></button>";
+
+        // add expand button
+        var pre_block = block.parentNode;
+        pre_block.insertBefore(buttons, pre_block.firstChild);
+
+        pre_block.querySelector('.buttons').addEventListener('click', function (e) {
+            if (e.target.classList.contains('fa-eye')) {
+                e.target.classList.remove('fa-eye');
+                e.target.classList.add('fa-eye-slash');
+                e.target.title = 'Hide lines';
+                e.target.setAttribute('aria-label', e.target.title);
+
+                block.classList.remove('hide-boring');
+            } else if (e.target.classList.contains('fa-eye-slash')) {
+                e.target.classList.remove('fa-eye-slash');
+                e.target.classList.add('fa-eye');
+                e.target.title = 'Show hidden lines';
+                e.target.setAttribute('aria-label', e.target.title);
+
+                block.classList.add('hide-boring');
+            }
+        });
+    });
+
+    if (window.playground_copyable) {
+        Array.from(document.querySelectorAll('pre code')).forEach(function (block) {
+            var pre_block = block.parentNode;
+            if (!pre_block.classList.contains('playground')) {
+                var buttons = pre_block.querySelector(".buttons");
+                if (!buttons) {
+                    buttons = document.createElement('div');
+                    buttons.className = 'buttons';
+                    pre_block.insertBefore(buttons, pre_block.firstChild);
+                }
+
+                var clipButton = document.createElement('button');
+                clipButton.className = 'fa fa-copy clip-button';
+                clipButton.title = 'Copy to clipboard';
+                clipButton.setAttribute('aria-label', clipButton.title);
+                clipButton.innerHTML = '<i class=\"tooltiptext\"></i>';
+
+                buttons.insertBefore(clipButton, buttons.firstChild);
+            }
+        });
+    }
+
+    // Process playground code blocks
+    Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) {
+        // Add play button
+        var buttons = pre_block.querySelector(".buttons");
+        if (!buttons) {
+            buttons = document.createElement('div');
+            buttons.className = 'buttons';
+            pre_block.insertBefore(buttons, pre_block.firstChild);
+        }
+
+        var runCodeButton = document.createElement('button');
+        runCodeButton.className = 'fa fa-play play-button';
+        runCodeButton.hidden = true;
+        runCodeButton.title = 'Run this code';
+        runCodeButton.setAttribute('aria-label', runCodeButton.title);
+
+        buttons.insertBefore(runCodeButton, buttons.firstChild);
+        runCodeButton.addEventListener('click', function (e) {
+            run_rust_code(pre_block);
+        });
+
+        if (window.playground_copyable) {
+            var copyCodeClipboardButton = document.createElement('button');
+            copyCodeClipboardButton.className = 'fa fa-copy clip-button';
+            copyCodeClipboardButton.innerHTML = '<i class="tooltiptext"></i>';
+            copyCodeClipboardButton.title = 'Copy to clipboard';
+            copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title);
+
+            buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild);
+        }
+
+        let code_block = pre_block.querySelector("code");
+        if (window.ace && code_block.classList.contains("editable")) {
+            var undoChangesButton = document.createElement('button');
+            undoChangesButton.className = 'fa fa-history reset-button';
+            undoChangesButton.title = 'Undo changes';
+            undoChangesButton.setAttribute('aria-label', undoChangesButton.title);
+
+            buttons.insertBefore(undoChangesButton, buttons.firstChild);
+
+            undoChangesButton.addEventListener('click', function () {
+                let editor = window.ace.edit(code_block);
+                editor.setValue(editor.originalCode);
+                editor.clearSelection();
+            });
+        }
+    });
+})();
+
+(function themes() {
+    var html = document.querySelector('html');
+    var themeToggleButton = document.getElementById('theme-toggle');
+    var themePopup = document.getElementById('theme-list');
+    var themeColorMetaTag = document.querySelector('meta[name="theme-color"]');
+    var stylesheets = {
+        ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"),
+        tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"),
+        highlight: document.querySelector("[href$='highlight.css']"),
+    };
+
+    function showThemes() {
+        themePopup.style.display = 'block';
+        themeToggleButton.setAttribute('aria-expanded', true);
+        themePopup.querySelector("button#" + get_theme()).focus();
+    }
+
+    function hideThemes() {
+        themePopup.style.display = 'none';
+        themeToggleButton.setAttribute('aria-expanded', false);
+        themeToggleButton.focus();
+    }
+
+    function get_theme() {
+        var theme;
+        try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { }
+        if (theme === null || theme === undefined) {
+            return default_theme;
+        } else {
+            return theme;
+        }
+    }
+
+    function set_theme(theme, store = true) {
+        let ace_theme;
+
+        if (theme == 'coal' || theme == 'navy') {
+            stylesheets.ayuHighlight.disabled = true;
+            stylesheets.tomorrowNight.disabled = false;
+            stylesheets.highlight.disabled = true;
+
+            ace_theme = "ace/theme/tomorrow_night";
+        } else if (theme == 'ayu') {
+            stylesheets.ayuHighlight.disabled = false;
+            stylesheets.tomorrowNight.disabled = true;
+            stylesheets.highlight.disabled = true;
+            ace_theme = "ace/theme/tomorrow_night";
+        } else {
+            stylesheets.ayuHighlight.disabled = true;
+            stylesheets.tomorrowNight.disabled = true;
+            stylesheets.highlight.disabled = false;
+            ace_theme = "ace/theme/dawn";
+        }
+
+        setTimeout(function () {
+            themeColorMetaTag.content = getComputedStyle(document.body).backgroundColor;
+        }, 1);
+
+        if (window.ace && window.editors) {
+            window.editors.forEach(function (editor) {
+                editor.setTheme(ace_theme);
+            });
+        }
+
+        var previousTheme = get_theme();
+
+        if (store) {
+            try { localStorage.setItem('mdbook-theme', theme); } catch (e) { }
+        }
+
+        html.classList.remove(previousTheme);
+        html.classList.add(theme);
+    }
+
+    // Set theme
+    var theme = get_theme();
+
+    set_theme(theme, false);
+
+    themeToggleButton.addEventListener('click', function () {
+        if (themePopup.style.display === 'block') {
+            hideThemes();
+        } else {
+            showThemes();
+        }
+    });
+
+    themePopup.addEventListener('click', function (e) {
+        var theme = e.target.id || e.target.parentElement.id;
+        set_theme(theme);
+    });
+
+    themePopup.addEventListener('focusout', function(e) {
+        // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below)
+        if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) {
+            hideThemes();
+        }
+    });
+
+    // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628
+    document.addEventListener('click', function(e) {
+        if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) {
+            hideThemes();
+        }
+    });
+
+    document.addEventListener('keydown', function (e) {
+        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
+        if (!themePopup.contains(e.target)) { return; }
+
+        switch (e.key) {
+            case 'Escape':
+                e.preventDefault();
+                hideThemes();
+                break;
+            case 'ArrowUp':
+                e.preventDefault();
+                var li = document.activeElement.parentElement;
+                if (li && li.previousElementSibling) {
+                    li.previousElementSibling.querySelector('button').focus();
+                }
+                break;
+            case 'ArrowDown':
+                e.preventDefault();
+                var li = document.activeElement.parentElement;
+                if (li && li.nextElementSibling) {
+                    li.nextElementSibling.querySelector('button').focus();
+                }
+                break;
+            case 'Home':
+                e.preventDefault();
+                themePopup.querySelector('li:first-child button').focus();
+                break;
+            case 'End':
+                e.preventDefault();
+                themePopup.querySelector('li:last-child button').focus();
+                break;
+        }
+    });
+})();
+
+(function sidebar() {
+    var html = document.querySelector("html");
+    var sidebar = document.getElementById("sidebar");
+    var sidebarLinks = document.querySelectorAll('#sidebar a');
+    var sidebarToggleButton = document.getElementById("sidebar-toggle");
+    var sidebarResizeHandle = document.getElementById("sidebar-resize-handle");
+    var firstContact = null;
+
+    function showSidebar() {
+        html.classList.remove('sidebar-hidden')
+        html.classList.add('sidebar-visible');
+        Array.from(sidebarLinks).forEach(function (link) {
+            link.setAttribute('tabIndex', 0);
+        });
+        sidebarToggleButton.setAttribute('aria-expanded', true);
+        sidebar.setAttribute('aria-hidden', false);
+        try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { }
+    }
+
+
+    var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle');
+
+    function toggleSection(ev) {
+        ev.currentTarget.parentElement.classList.toggle('expanded');
+    }
+
+    Array.from(sidebarAnchorToggles).forEach(function (el) {
+        el.addEventListener('click', toggleSection);
+    });
+
+    function hideSidebar() {
+        html.classList.remove('sidebar-visible')
+        html.classList.add('sidebar-hidden');
+        Array.from(sidebarLinks).forEach(function (link) {
+            link.setAttribute('tabIndex', -1);
+        });
+        sidebarToggleButton.setAttribute('aria-expanded', false);
+        sidebar.setAttribute('aria-hidden', true);
+        try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { }
+    }
+
+    // Toggle sidebar
+    sidebarToggleButton.addEventListener('click', function sidebarToggle() {
+        if (html.classList.contains("sidebar-hidden")) {
+            var current_width = parseInt(
+                document.documentElement.style.getPropertyValue('--sidebar-width'), 10);
+            if (current_width < 150) {
+                document.documentElement.style.setProperty('--sidebar-width', '150px');
+            }
+            showSidebar();
+        } else if (html.classList.contains("sidebar-visible")) {
+            hideSidebar();
+        } else {
+            if (getComputedStyle(sidebar)['transform'] === 'none') {
+                hideSidebar();
+            } else {
+                showSidebar();
+            }
+        }
+    });
+
+    sidebarResizeHandle.addEventListener('mousedown', initResize, false);
+
+    function initResize(e) {
+        window.addEventListener('mousemove', resize, false);
+        window.addEventListener('mouseup', stopResize, false);
+        html.classList.add('sidebar-resizing');
+    }
+    function resize(e) {
+        var pos = (e.clientX - sidebar.offsetLeft);
+        if (pos < 20) {
+            hideSidebar();
+        } else {
+            if (html.classList.contains("sidebar-hidden")) {
+                showSidebar();
+            }
+            pos = Math.min(pos, window.innerWidth - 100);
+            document.documentElement.style.setProperty('--sidebar-width', pos + 'px');
+        }
+    }
+    //on mouseup remove windows functions mousemove & mouseup
+    function stopResize(e) {
+        html.classList.remove('sidebar-resizing');
+        window.removeEventListener('mousemove', resize, false);
+        window.removeEventListener('mouseup', stopResize, false);
+    }
+
+    document.addEventListener('touchstart', function (e) {
+        firstContact = {
+            x: e.touches[0].clientX,
+            time: Date.now()
+        };
+    }, { passive: true });
+
+    document.addEventListener('touchmove', function (e) {
+        if (!firstContact)
+            return;
+
+        var curX = e.touches[0].clientX;
+        var xDiff = curX - firstContact.x,
+            tDiff = Date.now() - firstContact.time;
+
+        if (tDiff < 250 && Math.abs(xDiff) >= 150) {
+            if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300))
+                showSidebar();
+            else if (xDiff < 0 && curX < 300)
+                hideSidebar();
+
+            firstContact = null;
+        }
+    }, { passive: true });
+
+    // Scroll sidebar to current active section
+    var activeSection = document.getElementById("sidebar").querySelector(".active");
+    if (activeSection) {
+        // https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView
+        activeSection.scrollIntoView({ block: 'center' });
+    }
+})();
+
+(function chapterNavigation() {
+    document.addEventListener('keydown', function (e) {
+        if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; }
+        if (window.search && window.search.hasFocus()) { return; }
+
+        switch (e.key) {
+            case 'ArrowRight':
+                e.preventDefault();
+                var nextButton = document.querySelector('.nav-chapters.next');
+                if (nextButton) {
+                    window.location.href = nextButton.href;
+                }
+                break;
+            case 'ArrowLeft':
+                e.preventDefault();
+                var previousButton = document.querySelector('.nav-chapters.previous');
+                if (previousButton) {
+                    window.location.href = previousButton.href;
+                }
+                break;
+        }
+    });
+})();
+
+(function clipboard() {
+    var clipButtons = document.querySelectorAll('.clip-button');
+
+    function hideTooltip(elem) {
+        elem.firstChild.innerText = "";
+        elem.className = 'fa fa-copy clip-button';
+    }
+
+    function showTooltip(elem, msg) {
+        elem.firstChild.innerText = msg;
+        elem.className = 'fa fa-copy tooltipped';
+    }
+
+    var clipboardSnippets = new ClipboardJS('.clip-button', {
+        text: function (trigger) {
+            hideTooltip(trigger);
+            let playground = trigger.closest("pre");
+            return playground_text(playground);
+        }
+    });
+
+    Array.from(clipButtons).forEach(function (clipButton) {
+        clipButton.addEventListener('mouseout', function (e) {
+            hideTooltip(e.currentTarget);
+        });
+    });
+
+    clipboardSnippets.on('success', function (e) {
+        e.clearSelection();
+        showTooltip(e.trigger, "Copied!");
+    });
+
+    clipboardSnippets.on('error', function (e) {
+        showTooltip(e.trigger, "Clipboard error!");
+    });
+})();
+
+(function scrollToTop () {
+    var menuTitle = document.querySelector('.menu-title');
+
+    menuTitle.addEventListener('click', function () {
+        document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' });
+    });
+})();
+
+(function controllMenu() {
+    var menu = document.getElementById('menu-bar');
+
+    (function controllPosition() {
+        var scrollTop = document.scrollingElement.scrollTop;
+        var prevScrollTop = scrollTop;
+        var minMenuY = -menu.clientHeight - 50;
+        // When the script loads, the page can be at any scroll (e.g. if you reforesh it).
+        menu.style.top = scrollTop + 'px';
+        // Same as parseInt(menu.style.top.slice(0, -2), but faster
+        var topCache = menu.style.top.slice(0, -2);
+        menu.classList.remove('sticky');
+        var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster
+        document.addEventListener('scroll', function () {
+            scrollTop = Math.max(document.scrollingElement.scrollTop, 0);
+            // `null` means that it doesn't need to be updated
+            var nextSticky = null;
+            var nextTop = null;
+            var scrollDown = scrollTop > prevScrollTop;
+            var menuPosAbsoluteY = topCache - scrollTop;
+            if (scrollDown) {
+                nextSticky = false;
+                if (menuPosAbsoluteY > 0) {
+                    nextTop = prevScrollTop;
+                }
+            } else {
+                if (menuPosAbsoluteY > 0) {
+                    nextSticky = true;
+                } else if (menuPosAbsoluteY < minMenuY) {
+                    nextTop = prevScrollTop + minMenuY;
+                }
+            }
+            if (nextSticky === true && stickyCache === false) {
+                menu.classList.add('sticky');
+                stickyCache = true;
+            } else if (nextSticky === false && stickyCache === true) {
+                menu.classList.remove('sticky');
+                stickyCache = false;
+            }
+            if (nextTop !== null) {
+                menu.style.top = nextTop + 'px';
+                topCache = nextTop;
+            }
+            prevScrollTop = scrollTop;
+        }, { passive: true });
+    })();
+    (function controllBorder() {
+        menu.classList.remove('bordered');
+        document.addEventListener('scroll', function () {
+            if (menu.offsetTop === 0) {
+                menu.classList.remove('bordered');
+            } else {
+                menu.classList.add('bordered');
+            }
+        }, { passive: true });
+    })();
+})();
diff --git a/src/theme/css/chrome.css b/src/theme/css/chrome.css
new file mode 100644
index 0000000..9ca8633
--- /dev/null
+++ b/src/theme/css/chrome.css
@@ -0,0 +1,495 @@
+/* CSS for UI elements (a.k.a. chrome) */
+
+@import 'variables.css';
+
+::-webkit-scrollbar {
+    background: var(--bg);
+}
+::-webkit-scrollbar-thumb {
+    background: var(--scrollbar);
+}
+html {
+    scrollbar-color: var(--scrollbar) var(--bg);
+}
+#searchresults a,
+.content a:link,
+a:visited,
+a > .hljs {
+    color: var(--links);
+}
+
+/* Menu Bar */
+
+#menu-bar,
+#menu-bar-hover-placeholder {
+    z-index: 101;
+    margin: auto calc(0px - var(--page-padding));
+}
+#menu-bar {
+    position: relative;
+    display: flex;
+    flex-wrap: wrap;
+    background-color: var(--bg);
+    border-bottom-color: var(--bg);
+    border-bottom-width: 1px;
+    border-bottom-style: solid;
+}
+#menu-bar.sticky,
+.js #menu-bar-hover-placeholder:hover + #menu-bar,
+.js #menu-bar:hover,
+.js.sidebar-visible #menu-bar {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0 !important;
+}
+#menu-bar-hover-placeholder {
+    position: sticky;
+    position: -webkit-sticky;
+    top: 0;
+    height: var(--menu-bar-height);
+}
+#menu-bar.bordered {
+    border-bottom-color: var(--table-border-color);
+}
+#menu-bar i, #menu-bar .icon-button {
+    position: relative;
+    padding: 0 8px;
+    z-index: 10;
+    line-height: var(--menu-bar-height);
+    cursor: pointer;
+    transition: color 0.5s;
+}
+@media only screen and (max-width: 420px) {
+    #menu-bar i, #menu-bar .icon-button {
+        padding: 0 5px;
+    }
+}
+
+.icon-button {
+    border: none;
+    background: none;
+    padding: 0;
+    color: inherit;
+}
+.icon-button i {
+    margin: 0;
+}
+
+.right-buttons {
+    margin: 0 15px;
+}
+.right-buttons a {
+    text-decoration: none;
+}
+
+.left-buttons {
+    display: flex;
+    margin: 0 5px;
+}
+.no-js .left-buttons {
+    display: none;
+}
+
+.menu-title {
+    display: inline-block;
+    font-weight: 200;
+    font-size: 2rem;
+    line-height: var(--menu-bar-height);
+    text-align: center;
+    margin: 0;
+    flex: 1;
+    white-space: nowrap;
+    overflow: hidden;
+    text-overflow: ellipsis;
+}
+.js .menu-title {
+    cursor: pointer;
+}
+
+.menu-bar,
+.menu-bar:visited,
+.nav-chapters,
+.nav-chapters:visited,
+.mobile-nav-chapters,
+.mobile-nav-chapters:visited,
+.menu-bar .icon-button,
+.menu-bar a i {
+    color: var(--icons);
+}
+
+.menu-bar i:hover,
+.menu-bar .icon-button:hover,
+.nav-chapters:hover,
+.mobile-nav-chapters i:hover {
+    color: var(--icons-hover);
+}
+
+/* Nav Icons */
+
+.nav-chapters {
+    font-size: 2.5em;
+    text-align: center;
+    text-decoration: none;
+
+    position: fixed;
+    top: 0;
+    bottom: 0;
+    margin: 0;
+    max-width: 150px;
+    min-width: 90px;
+
+    display: flex;
+    justify-content: center;
+    align-content: center;
+    flex-direction: column;
+
+    transition: color 0.5s, background-color 0.5s;
+}
+
+.nav-chapters:hover {
+    text-decoration: none;
+    background-color: var(--theme-hover);
+    transition: background-color 0.15s, color 0.15s;
+}
+
+.nav-wrapper {
+    margin-top: 50px;
+    display: none;
+}
+
+.mobile-nav-chapters {
+    font-size: 2.5em;
+    text-align: center;
+    text-decoration: none;
+    width: 90px;
+    border-radius: 5px;
+    background-color: var(--sidebar-bg);
+}
+
+.previous {
+    float: left;
+}
+
+.next {
+    float: right;
+    right: var(--page-padding);
+}
+
+@media only screen and (max-width: 1080px) {
+    .nav-wide-wrapper { display: none; }
+    .nav-wrapper { display: block; }
+}
+
+@media only screen and (max-width: 1380px) {
+    .sidebar-visible .nav-wide-wrapper { display: none; }
+    .sidebar-visible .nav-wrapper { display: block; }
+}
+
+/* Inline code */
+
+:not(pre) > .hljs {
+    display: inline;
+    padding: 0.1em 0.3em;
+    border-radius: 3px;
+}
+
+:not(pre):not(a) > .hljs {
+    color: var(--inline-code-color);
+    overflow-x: initial;
+}
+
+a:hover > .hljs {
+    text-decoration: underline;
+}
+
+pre {
+    position: relative;
+}
+pre > .buttons {
+    position: absolute;
+    z-index: 100;
+    right: 5px;
+    top: 5px;
+
+    color: var(--sidebar-fg);
+    cursor: pointer;
+}
+pre > .buttons :hover {
+    color: var(--sidebar-active);
+}
+pre > .buttons i {
+    margin-left: 8px;
+}
+pre > .buttons button {
+    color: inherit;
+    background: transparent;
+    border: none;
+    cursor: inherit;
+}
+pre > .result {
+    margin-top: 10px;
+}
+
+/* Search */
+
+#searchresults a {
+    text-decoration: none;
+}
+
+mark {
+    border-radius: 2px;
+    padding: 0 3px 1px 3px;
+    margin: 0 -3px -1px -3px;
+    background-color: var(--search-mark-bg);
+    transition: background-color 300ms linear;
+    cursor: pointer;
+}
+
+mark.fade-out {
+    background-color: rgba(0,0,0,0) !important;
+    cursor: auto;
+}
+
+.searchbar-outer {
+    margin-left: auto;
+    margin-right: auto;
+    max-width: var(--content-max-width);
+}
+
+#searchbar {
+    width: 100%;
+    margin: 5px auto 0px auto;
+    padding: 10px 16px;
+    transition: box-shadow 300ms ease-in-out;
+    border: 1px solid var(--searchbar-border-color);
+    border-radius: 3px;
+    background-color: var(--searchbar-bg);
+    color: var(--searchbar-fg);
+}
+#searchbar:focus,
+#searchbar.active {
+    box-shadow: 0 0 3px var(--searchbar-shadow-color);
+}
+
+.searchresults-header {
+    font-weight: bold;
+    font-size: 1em;
+    padding: 18px 0 0 5px;
+    color: var(--searchresults-header-fg);
+}
+
+.searchresults-outer {
+    margin-left: auto;
+    margin-right: auto;
+    max-width: var(--content-max-width);
+    border-bottom: 1px dashed var(--searchresults-border-color);
+}
+
+ul#searchresults {
+    list-style: none;
+    padding-left: 20px;
+}
+ul#searchresults li {
+    margin: 10px 0px;
+    padding: 2px;
+    border-radius: 2px;
+}
+ul#searchresults li.focus {
+    background-color: var(--searchresults-li-bg);
+}
+ul#searchresults span.teaser {
+    display: block;
+    clear: both;
+    margin: 5px 0 0 20px;
+    font-size: 0.8em;
+}
+ul#searchresults span.teaser em {
+    font-weight: bold;
+    font-style: normal;
+}
+
+/* Sidebar */
+
+.sidebar {
+    position: fixed;
+    left: 0;
+    top: 0;
+    bottom: 0;
+    width: var(--sidebar-width);
+    font-size: 0.875em;
+    box-sizing: border-box;
+    -webkit-overflow-scrolling: touch;
+    overscroll-behavior-y: contain;
+    background-color: var(--sidebar-bg);
+    color: var(--sidebar-fg);
+}
+.sidebar-resizing {
+    -moz-user-select: none;
+    -webkit-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+}
+.js:not(.sidebar-resizing) .sidebar {
+    transition: transform 0.3s; /* Animation: slide away */
+}
+.sidebar code {
+    line-height: 2em;
+}
+.sidebar .sidebar-scrollbox {
+    overflow-y: auto;
+    position: absolute;
+    top: 0;
+    bottom: 0;
+    left: 0;
+    right: 0;
+    padding: 10px 10px;
+}
+.sidebar .sidebar-resize-handle {
+    position: absolute;
+    cursor: col-resize;
+    width: 0;
+    right: 0;
+    top: 0;
+    bottom: 0;
+}
+.js .sidebar .sidebar-resize-handle {
+    cursor: col-resize;
+    width: 5px;
+}
+.sidebar-hidden .sidebar {
+    transform: translateX(calc(0px - var(--sidebar-width)));
+}
+.sidebar::-webkit-scrollbar {
+    background: var(--sidebar-bg);
+}
+.sidebar::-webkit-scrollbar-thumb {
+    background: var(--scrollbar);
+}
+
+.sidebar-visible .page-wrapper {
+    transform: translateX(var(--sidebar-width));
+}
+@media only screen and (min-width: 620px) {
+    .sidebar-visible .page-wrapper {
+        transform: none;
+        margin-left: var(--sidebar-width);
+    }
+}
+
+.chapter {
+    list-style: none outside none;
+    padding-left: 0;
+    line-height: 2.2em;
+}
+
+.chapter ol {
+    width: 100%;
+}
+
+.chapter li {
+    display: flex;
+    color: var(--sidebar-non-existant);
+}
+.chapter li a {
+    display: block;
+    padding: 0;
+    text-decoration: none;
+    color: var(--sidebar-fg);
+}
+
+.chapter li a:hover {
+    color: var(--sidebar-active);
+}
+
+.chapter li a.active {
+    color: var(--sidebar-active);
+}
+
+.chapter li > a.toggle {
+    cursor: pointer;
+    display: block;
+    margin-left: auto;
+    padding: 0 10px;
+    user-select: none;
+    opacity: 0.68;
+}
+
+.chapter li > a.toggle div {
+    transition: transform 0.5s;
+}
+
+/* collapse the section */
+.chapter li:not(.expanded) + li > ol {
+    display: none;
+}
+
+.chapter li.chapter-item {
+    line-height: 1.5em;
+    margin-top: 0.6em;
+}
+
+.chapter li.expanded > a.toggle div {
+    transform: rotate(90deg);
+}
+
+.spacer {
+    width: 100%;
+    height: 3px;
+    margin: 5px 0px;
+}
+.chapter .spacer {
+    background-color: var(--sidebar-spacer);
+}
+
+@media (-moz-touch-enabled: 1), (pointer: coarse) {
+    .chapter li a { padding: 5px 0; }
+    .spacer { margin: 10px 0; }
+}
+
+.section {
+    list-style: none outside none;
+    padding-left: 20px;
+    line-height: 1.9em;
+}
+
+/* Theme Menu Popup */
+
+.theme-popup {
+    position: absolute;
+    left: 10px;
+    top: var(--menu-bar-height);
+    z-index: 1000;
+    border-radius: 4px;
+    font-size: 0.7em;
+    color: var(--fg);
+    background: var(--theme-popup-bg);
+    border: 1px solid var(--theme-popup-border);
+    margin: 0;
+    padding: 0;
+    list-style: none;
+    display: none;
+}
+.theme-popup .default {
+    color: var(--icons);
+}
+.theme-popup .theme {
+    width: 100%;
+    border: 0;
+    margin: 0;
+    padding: 2px 10px;
+    line-height: 25px;
+    white-space: nowrap;
+    text-align: left;
+    cursor: pointer;
+    color: inherit;
+    background: inherit;
+    font-size: inherit;
+}
+.theme-popup .theme:hover {
+    background-color: var(--theme-hover);
+}
+.theme-popup .theme:hover:first-child,
+.theme-popup .theme:hover:last-child {
+    border-top-left-radius: inherit;
+    border-top-right-radius: inherit;
+}
diff --git a/src/theme/css/general.css b/src/theme/css/general.css
new file mode 100644
index 0000000..815dae1
--- /dev/null
+++ b/src/theme/css/general.css
@@ -0,0 +1,174 @@
+/* Base styles and content styles */
+
+@import 'variables.css';
+
+:root {
+    /* Browser default font-size is 16px, this way 1 rem = 10px */
+    font-size: 62.5%;
+}
+
+html {
+    font-family: "Open Sans", sans-serif;
+    color: var(--fg);
+    background-color: var(--bg);
+    text-size-adjust: none;
+}
+
+body {
+    margin: 0;
+    font-size: 1.6rem;
+    overflow-x: hidden;
+}
+
+code {
+    font-family: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace !important;
+    font-size: 0.875em; /* please adjust the ace font size accordingly in editor.js */
+}
+
+/* Don't change font size in headers. */
+h1 code, h2 code, h3 code, h4 code, h5 code, h6 code {
+    font-size: unset;
+}
+
+.left { float: left; }
+.right { float: right; }
+.boring { opacity: 0.6; }
+.hide-boring .boring { display: none; }
+.hidden { display: none !important; }
+
+h2, h3 { margin-top: 2.5em; }
+h4, h5 { margin-top: 2em; }
+
+.header + .header h3,
+.header + .header h4,
+.header + .header h5 {
+    margin-top: 1em;
+}
+
+h1 a.header:target::before,
+h2 a.header:target::before,
+h3 a.header:target::before,
+h4 a.header:target::before {
+    display: inline-block;
+    content: "»";
+    margin-left: -30px;
+    width: 30px;
+}
+
+h1 a.header:target,
+h2 a.header:target,
+h3 a.header:target,
+h4 a.header:target {
+    scroll-margin-top: calc(var(--menu-bar-height) + 0.5em);
+}
+
+.page {
+    outline: 0;
+    padding: 0 var(--page-padding);
+    margin-top: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */
+}
+.page-wrapper {
+    box-sizing: border-box;
+}
+.js:not(.sidebar-resizing) .page-wrapper {
+    transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */
+}
+
+.content {
+    overflow-y: auto;
+    padding: 0 15px;
+    padding-bottom: 50px;
+}
+.content main {
+    margin-left: auto;
+    margin-right: auto;
+    max-width: var(--content-max-width);
+}
+.content p { line-height: 1.45em; }
+.content ol { line-height: 1.45em; }
+.content ul { line-height: 1.45em; }
+.content a { text-decoration: none; }
+.content a:hover { text-decoration: underline; }
+.content img { max-width: 100%; }
+.content .header:link,
+.content .header:visited {
+    color: var(--fg);
+}
+.content .header:link,
+.content .header:visited:hover {
+    text-decoration: none;
+}
+
+table {
+    margin: 0 auto;
+    border-collapse: collapse;
+}
+table td {
+    padding: 3px 20px;
+    border: 1px var(--table-border-color) solid;
+}
+table thead {
+    background: var(--table-header-bg);
+}
+table thead td {
+    font-weight: 700;
+    border: none;
+}
+table thead th {
+    padding: 3px 20px;
+}
+table thead tr {
+    border: 1px var(--table-header-bg) solid;
+}
+/* Alternate background colors for rows */
+table tbody tr:nth-child(2n) {
+    background: var(--table-alternate-bg);
+}
+
+
+blockquote {
+    margin: 20px 0;
+    padding: 0 20px;
+    color: var(--fg);
+    background-color: var(--quote-bg);
+    border-top: .1em solid var(--quote-border);
+    border-bottom: .1em solid var(--quote-border);
+}
+
+
+:not(.footnote-definition) + .footnote-definition,
+.footnote-definition + :not(.footnote-definition) {
+    margin-top: 2em;
+}
+.footnote-definition {
+    font-size: 0.9em;
+    margin: 0.5em 0;
+}
+.footnote-definition p {
+    display: inline;
+}
+
+.tooltiptext {
+    position: absolute;
+    visibility: hidden;
+    color: #fff;
+    background-color: #333;
+    transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */
+    left: -8px; /* Half of the width of the icon */
+    top: -35px;
+    font-size: 0.8em;
+    text-align: center;
+    border-radius: 6px;
+    padding: 5px 8px;
+    margin: 5px;
+    z-index: 1000;
+}
+.tooltipped .tooltiptext {
+    visibility: visible;
+}
+
+.chapter li.part-title {
+    color: var(--sidebar-fg);
+    margin: 5px 0px;
+    font-weight: bold;
+}
diff --git a/src/theme/css/print.css b/src/theme/css/print.css
new file mode 100644
index 0000000..5e690f7
--- /dev/null
+++ b/src/theme/css/print.css
@@ -0,0 +1,54 @@
+
+#sidebar,
+#menu-bar,
+.nav-chapters,
+.mobile-nav-chapters {
+    display: none;
+}
+
+#page-wrapper.page-wrapper {
+    transform: none;
+    margin-left: 0px;
+    overflow-y: initial;
+}
+
+#content {
+    max-width: none;
+    margin: 0;
+    padding: 0;
+}
+
+.page {
+    overflow-y: initial;
+}
+
+code {
+    background-color: #666666;
+    border-radius: 5px;
+
+    /* Force background to be printed in Chrome */
+    -webkit-print-color-adjust: exact;
+}
+
+pre > .buttons {
+    z-index: 2;
+}
+
+a, a:visited, a:active, a:hover {
+    color: #4183c4;
+    text-decoration: none;
+}
+
+h1, h2, h3, h4, h5, h6 {
+    page-break-inside: avoid;
+    page-break-after: avoid;
+}
+
+pre, code {
+    page-break-inside: avoid;
+    white-space: pre-wrap;
+}
+
+.fa {
+    display: none !important;
+}
diff --git a/src/theme/css/variables.css b/src/theme/css/variables.css
new file mode 100644
index 0000000..9534ec8
--- /dev/null
+++ b/src/theme/css/variables.css
@@ -0,0 +1,253 @@
+
+/* Globals */
+
+:root {
+    --sidebar-width: 300px;
+    --page-padding: 15px;
+    --content-max-width: 750px;
+    --menu-bar-height: 50px;
+}
+
+/* Themes */
+
+.ayu {
+    --bg: hsl(210, 25%, 8%);
+    --fg: #c5c5c5;
+
+    --sidebar-bg: #14191f;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #5c6773;
+    --sidebar-active: #ffb454;
+    --sidebar-spacer: #2d334f;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #737480;
+    --icons-hover: #b7b9cc;
+
+    --links: #0096cf;
+
+    --inline-code-color: #ffb454;
+
+    --theme-popup-bg: #14191f;
+    --theme-popup-border: #5c6773;
+    --theme-hover: #191f26;
+
+    --quote-bg: hsl(226, 15%, 17%);
+    --quote-border: hsl(226, 15%, 22%);
+
+    --table-border-color: hsl(210, 25%, 13%);
+    --table-header-bg: hsl(210, 25%, 28%);
+    --table-alternate-bg: hsl(210, 25%, 11%);
+
+    --searchbar-border-color: #848484;
+    --searchbar-bg: #424242;
+    --searchbar-fg: #fff;
+    --searchbar-shadow-color: #d4c89f;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #252932;
+    --search-mark-bg: #e3b171;
+}
+
+.coal {
+    --bg: hsl(200, 7%, 8%);
+    --fg: #98a3ad;
+
+    --sidebar-bg: #292c2f;
+    --sidebar-fg: #a1adb8;
+    --sidebar-non-existant: #505254;
+    --sidebar-active: #3473ad;
+    --sidebar-spacer: #393939;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #43484d;
+    --icons-hover: #b3c0cc;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #c5c8c6;;
+
+    --theme-popup-bg: #141617;
+    --theme-popup-border: #43484d;
+    --theme-hover: #1f2124;
+
+    --quote-bg: hsl(234, 21%, 18%);
+    --quote-border: hsl(234, 21%, 23%);
+
+    --table-border-color: hsl(200, 7%, 13%);
+    --table-header-bg: hsl(200, 7%, 28%);
+    --table-alternate-bg: hsl(200, 7%, 11%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #b7b7b7;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #98a3ad;
+    --searchresults-li-bg: #2b2b2f;
+    --search-mark-bg: #355c7d;
+}
+
+.light {
+    --bg: hsl(0, 0%, 100%);
+    --fg: #333333;
+
+    --sidebar-bg: #fafafa;
+    --sidebar-fg: #364149;
+    --sidebar-non-existant: #aaaaaa;
+    --sidebar-active: #008cff;
+    --sidebar-spacer: #f4f4f4;
+
+    --scrollbar: #cccccc;
+
+    --icons: #cccccc;
+    --icons-hover: #333333;
+
+    --links: #4183c4;
+
+    --inline-code-color: #6e6b5e;
+
+    --theme-popup-bg: #fafafa;
+    --theme-popup-border: #cccccc;
+    --theme-hover: #e6e6e6;
+
+    --quote-bg: hsl(197, 37%, 96%);
+    --quote-border: hsl(197, 37%, 91%);
+
+    --table-border-color: hsl(0, 0%, 95%);
+    --table-header-bg: hsl(0, 0%, 80%);
+    --table-alternate-bg: hsl(0, 0%, 97%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #fafafa;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #e4f2fe;
+    --search-mark-bg: #a2cff5;
+}
+
+.navy {
+    --bg: hsl(226, 23%, 11%);
+    --fg: #bcbdd0;
+
+    --sidebar-bg: #282d3f;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #505274;
+    --sidebar-active: #2b79a2;
+    --sidebar-spacer: #2d334f;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #737480;
+    --icons-hover: #b7b9cc;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #c5c8c6;;
+
+    --theme-popup-bg: #161923;
+    --theme-popup-border: #737480;
+    --theme-hover: #282e40;
+
+    --quote-bg: hsl(226, 15%, 17%);
+    --quote-border: hsl(226, 15%, 22%);
+
+    --table-border-color: hsl(226, 23%, 16%);
+    --table-header-bg: hsl(226, 23%, 31%);
+    --table-alternate-bg: hsl(226, 23%, 14%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #aeaec6;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #5f5f71;
+    --searchresults-border-color: #5c5c68;
+    --searchresults-li-bg: #242430;
+    --search-mark-bg: #a2cff5;
+}
+
+.rust {
+    --bg: hsl(60, 9%, 87%);
+    --fg: #262625;
+
+    --sidebar-bg: #3b2e2a;
+    --sidebar-fg: #c8c9db;
+    --sidebar-non-existant: #505254;
+    --sidebar-active: #e69f67;
+    --sidebar-spacer: #45373a;
+
+    --scrollbar: var(--sidebar-fg);
+
+    --icons: #737480;
+    --icons-hover: #262625;
+
+    --links: #2b79a2;
+
+    --inline-code-color: #6e6b5e;
+
+    --theme-popup-bg: #e1e1db;
+    --theme-popup-border: #b38f6b;
+    --theme-hover: #99908a;
+
+    --quote-bg: hsl(60, 5%, 75%);
+    --quote-border: hsl(60, 5%, 70%);
+
+    --table-border-color: hsl(60, 9%, 82%);
+    --table-header-bg: #b3a497;
+    --table-alternate-bg: hsl(60, 9%, 84%);
+
+    --searchbar-border-color: #aaa;
+    --searchbar-bg: #fafafa;
+    --searchbar-fg: #000;
+    --searchbar-shadow-color: #aaa;
+    --searchresults-header-fg: #666;
+    --searchresults-border-color: #888;
+    --searchresults-li-bg: #dec2a2;
+    --search-mark-bg: #e69f67;
+}
+
+@media (prefers-color-scheme: dark) {
+    .light.no-js {
+        --bg: hsl(200, 7%, 8%);
+        --fg: #98a3ad;
+
+        --sidebar-bg: #292c2f;
+        --sidebar-fg: #a1adb8;
+        --sidebar-non-existant: #505254;
+        --sidebar-active: #3473ad;
+        --sidebar-spacer: #393939;
+
+        --scrollbar: var(--sidebar-fg);
+
+        --icons: #43484d;
+        --icons-hover: #b3c0cc;
+
+        --links: #2b79a2;
+
+        --inline-code-color: #c5c8c6;;
+
+        --theme-popup-bg: #141617;
+        --theme-popup-border: #43484d;
+        --theme-hover: #1f2124;
+
+        --quote-bg: hsl(234, 21%, 18%);
+        --quote-border: hsl(234, 21%, 23%);
+
+        --table-border-color: hsl(200, 7%, 13%);
+        --table-header-bg: hsl(200, 7%, 28%);
+        --table-alternate-bg: hsl(200, 7%, 11%);
+
+        --searchbar-border-color: #aaa;
+        --searchbar-bg: #b7b7b7;
+        --searchbar-fg: #000;
+        --searchbar-shadow-color: #aaa;
+        --searchresults-header-fg: #666;
+        --searchresults-border-color: #98a3ad;
+        --searchresults-li-bg: #2b2b2f;
+        --search-mark-bg: #355c7d;
+    }
+}
diff --git a/src/theme/favicon.png b/src/theme/favicon.png
new file mode 100644
index 0000000000000000000000000000000000000000..a5b1aa16c4dcb6c872cb5af799bfc9b5552c7b9e
GIT binary patch
diff --git a/src/theme/favicon.svg b/src/theme/favicon.svg
new file mode 100644
index 0000000..90e0ea5
--- /dev/null
+++ b/src/theme/favicon.svg
@@ -0,0 +1,22 @@
+<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 199.7 184.2">
+  <style>
+    @media (prefers-color-scheme: dark) {
+      svg { fill: white; }
+    }
+  </style>
+<path d="M189.5,36.8c0.2,2.8,0,5.1-0.6,6.8L153,162c-0.6,2.1-2,3.7-4.2,5c-2.2,1.2-4.4,1.9-6.7,1.9H31.4c-9.6,0-15.3-2.8-17.3-8.4
+  c-0.8-2.2-0.8-3.9,0.1-5.2c0.9-1.2,2.4-1.8,4.6-1.8H123c7.4,0,12.6-1.4,15.4-4.1s5.7-8.9,8.6-18.4l32.9-108.6
+  c1.8-5.9,1-11.1-2.2-15.6S169.9,0,164,0H72.7c-1,0-3.1,0.4-6.1,1.1l0.1-0.4C64.5,0.2,62.6,0,61,0.1s-3,0.5-4.3,1.4
+  c-1.3,0.9-2.4,1.8-3.2,2.8S52,6.5,51.2,8.1c-0.8,1.6-1.4,3-1.9,4.3s-1.1,2.7-1.8,4.2c-0.7,1.5-1.3,2.7-2,3.7c-0.5,0.6-1.2,1.5-2,2.5
+  s-1.6,2-2.2,2.8s-0.9,1.5-1.1,2.2c-0.2,0.7-0.1,1.8,0.2,3.2c0.3,1.4,0.4,2.4,0.4,3.1c-0.3,3-1.4,6.9-3.3,11.6
+  c-1.9,4.7-3.6,8.1-5.1,10.1c-0.3,0.4-1.2,1.3-2.6,2.7c-1.4,1.4-2.3,2.6-2.6,3.7c-0.3,0.4-0.3,1.5-0.1,3.4c0.3,1.8,0.4,3.1,0.3,3.8
+  c-0.3,2.7-1.3,6.3-3,10.8c-1.7,4.5-3.4,8.2-5,11c-0.2,0.5-0.9,1.4-2,2.8c-1.1,1.4-1.8,2.5-2,3.4c-0.2,0.6-0.1,1.8,0.1,3.4
+  c0.2,1.6,0.2,2.8-0.1,3.6c-0.6,3-1.8,6.7-3.6,11c-1.8,4.3-3.6,7.9-5.4,11c-0.5,0.8-1.1,1.7-2,2.8c-0.8,1.1-1.5,2-2,2.8
+  s-0.8,1.6-1,2.5c-0.1,0.5,0,1.3,0.4,2.3c0.3,1.1,0.4,1.9,0.4,2.6c-0.1,1.1-0.2,2.6-0.5,4.4c-0.2,1.8-0.4,2.9-0.4,3.2
+  c-1.8,4.8-1.7,9.9,0.2,15.2c2.2,6.2,6.2,11.5,11.9,15.8c5.7,4.3,11.7,6.4,17.8,6.4h110.7c5.2,0,10.1-1.7,14.7-5.2s7.7-7.8,9.2-12.9
+  l33-108.6c1.8-5.8,1-10.9-2.2-15.5C194.9,39.7,192.6,38,189.5,36.8z M59.6,122.8L73.8,80c0,0,7,0,10.8,0s28.8-1.7,25.4,17.5
+  c-3.4,19.2-18.8,25.2-36.8,25.4S59.6,122.8,59.6,122.8z M78.6,116.8c4.7-0.1,18.9-2.9,22.1-17.1S89.2,86.3,89.2,86.3l-8.9,0
+  l-10.2,30.5C70.2,116.9,74,116.9,78.6,116.8z M75.3,68.7L89,26.2h9.8l0.8,34l23.6-34h9.9l-13.6,42.5h-7.1l12.5-35.4l-24.5,35.4h-6.8
+  l-0.8-35L82,68.7H75.3z"/>
+</svg>
+<!-- Original image Copyright Dave Gandy — CC BY 4.0 License -->
diff --git a/src/theme/highlight.css b/src/theme/highlight.css
new file mode 100644
index 0000000..ab8c49c
--- /dev/null
+++ b/src/theme/highlight.css
@@ -0,0 +1,79 @@
+/* Base16 Atelier Dune Light - Theme */
+/* by Bram de Haan (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) */
+/* Original Base16 color scheme by Chris Kempson (https://github.com/chriskempson/base16) */
+
+/* Atelier-Dune Comment */
+.hljs-comment,
+.hljs-quote {
+  color: #AAA;
+}
+
+/* Atelier-Dune Red */
+.hljs-variable,
+.hljs-template-variable,
+.hljs-attribute,
+.hljs-tag,
+.hljs-name,
+.hljs-regexp,
+.hljs-link,
+.hljs-name,
+.hljs-selector-id,
+.hljs-selector-class {
+  color: #d73737;
+}
+
+/* Atelier-Dune Orange */
+.hljs-number,
+.hljs-meta,
+.hljs-built_in,
+.hljs-builtin-name,
+.hljs-literal,
+.hljs-type,
+.hljs-params {
+  color: #b65611;
+}
+
+/* Atelier-Dune Green */
+.hljs-string,
+.hljs-symbol,
+.hljs-bullet {
+  color: #60ac39;
+}
+
+/* Atelier-Dune Blue */
+.hljs-title,
+.hljs-section {
+  color: #6684e1;
+}
+
+/* Atelier-Dune Purple */
+.hljs-keyword,
+.hljs-selector-tag {
+  color: #b854d4;
+}
+
+.hljs {
+  display: block;
+  overflow-x: auto;
+  background: #f1f1f1;
+  color: #6e6b5e;
+  padding: 0.5em;
+}
+
+.hljs-emphasis {
+  font-style: italic;
+}
+
+.hljs-strong {
+  font-weight: bold;
+}
+
+.hljs-addition {
+  color: #22863a;
+  background-color: #f0fff4;
+}
+
+.hljs-deletion {
+  color: #b31d28;
+  background-color: #ffeef0;
+}
diff --git a/src/theme/highlight.js b/src/theme/highlight.js
new file mode 100644
index 0000000..180385b
--- /dev/null
+++ b/src/theme/highlight.js
@@ -0,0 +1,6 @@
+/*
+  Highlight.js 10.1.1 (93fd0d73)
+  License: BSD-3-Clause
+  Copyright (c) 2006-2020, Ivan Sagalaev
+*/
+var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){s+="<"+a(e)+[].map.call(e.attributes,(function(e){return" "+e.nodeName+'="'+t(e.value)+'"'})).join("")+">"}function u(e){s+="</"+a(e)+">"}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="</span>",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=`<span class="${e}">`}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[h,{begin:/\[/,end:/\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),N="of and for in not or if then".split(" ");function w(e,n){return n?+n:function(e){return N.includes(e.toLowerCase())}(e)?0:1}const R=t,y=r,{nodeStream:k,mergeStreams:O}=i,M=Symbol("nomatch");return function(t){var a=[],i={},s={},o=[],l=!0,c=/(^(<[^>]+>|\t|)+|\n)/gm,g="Could not find the language '{}', did you forget to load/include a language module?";const h={disableAutodetect:!0,name:"Plain text",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function b(e,n,t,r){var a={code:n,language:e};S("before:highlight",a);var i=a.result?a.result:m(a.language,a.code,t,r);return i.code=a.code,S("after:highlight",i),i}function m(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=y.subLanguage?function(){if(""!==A){var e=null;if("string"==typeof y.subLanguage){if(!i[y.subLanguage])return void O.addText(A);e=m(y.subLanguage,A,!0,k[y.subLanguage]),k[y.subLanguage]=e.top}else e=v(A,y.subLanguage.length?y.subLanguage:null);y.relevance>0&&(I+=e.relevance),O.addSublanguage(e.emitter,e.language)}}():function(){if(!y.keywords)return void O.addText(A);let e=0;y.keywordPatternRe.lastIndex=0;let n=y.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const r=c(y,n);if(r){const[e,a]=r;O.addText(t),t="",I+=a,O.addKeyword(n[0],e)}else t+=n[0];e=y.keywordPatternRe.lastIndex,n=y.keywordPatternRe.exec(A)}t+=A.substr(e),O.addText(t)}(),A=""}function h(e){return e.className&&O.openNode(e.className),y=Object.create(e,{parent:{value:y}})}function p(e){return 0===y.matcher.regexIndex?(A+=e[0],1):(L=!0,0)}var b={};function x(t,r){var i=r&&r[0];if(A+=t,null==i)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===i){if(A+=o.slice(r.index,r.index+1),!l){const n=Error("0 width match regex");throw n.languageName=e,n.badRule=b.rule,n}return 1}if(b=r,"begin"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r["on:begin"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),r.skip?A+=t:(r.excludeBegin&&(A+=t),u(),r.returnBegin||r.excludeBegin||(A=t)),h(r),r.returnBegin?0:t.length}(r);if("illegal"===r.type&&!a){const e=Error('Illegal lexeme "'+i+'" for mode "'+(y.className||"<unnamed>")+'"');throw e.mode=y,e}if("end"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t["on:end"]){const e=new n(t);t["on:end"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(y,e,r);if(!a)return M;var i=y;i.skip?A+=t:(i.returnEnd||i.excludeEnd||(A+=t),u(),i.excludeEnd&&(A=t));do{y.className&&O.closeNode(),y.skip||y.subLanguage||(I+=y.relevance),y=y.parent}while(y!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==M)return s}if("illegal"===r.type&&""===i)return 1;if(B>1e5&&B>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=i,i.length}var E=T(e);if(!E)throw console.error(g.replace("{}",e)),Error('Unknown language: "'+e+'"');var _=function(e){function n(n,t){return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n="|"){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var s=r+=1,o=d(e[i]);for(i>0&&(a+=n),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"===l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("===l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];"."!==t&&"."!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if("object"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,w(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l.keywordPatternRe=n(s.lexemes||c||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__beforeBegin=i),s.begin||(s.begin=/\B|\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=d(s.end)||"",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(l),l}(e)}(E),N="",y=s||_,k={},O=new f.__emitter(f);!function(){for(var e=[],n=y;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>O.openNode(e))}();var A="",I=0,S=0,B=0,L=!1;try{for(y.matcher.considerAll();;){B++,L?L=!1:(y.matcher.lastIndex=S,y.matcher.considerAll());const e=y.matcher.exec(o);if(!e)break;const n=x(o.substring(S,e.index),e);S=e.index+n}return x(o.substr(S)),O.closeAllNodes(),O.finalize(),N=O.toHTML(),{relevance:I,value:N,language:e,illegal:!1,emitter:O,top:y}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(S-100,S+100),mode:n.mode},sofar:N,relevance:0,value:R(o),emitter:O};if(l)return{illegal:!1,relevance:0,value:R(o),emitter:O,language:e,top:y,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:R(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(T).filter(I).forEach((function(n){var a=m(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>"\n"===e?f.useBR?"<br>":e:f.tabReplace?e.replace(/\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=f.languageDetectRe.exec(n);if(t){var r=T(t[1]);return r||(console.warn(g.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?t[1]:"no-highlight"}return n.split(/\s+/).find(e=>p(e)||T(e))}(e);if(p(t))return;S("before:highlightBlock",{block:e,language:t}),f.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ /]*>/g,"\n"):n=e;const r=n.textContent,a=t?b(t,r,!0):v(r),i=k(n);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=O(i,k(e),r)}a.value=x(a.value),S("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const N=()=>{if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");a.forEach.call(e,E)}};function T(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}function A(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function I(e){var n=T(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:b,highlightAuto:v,fixMarkup:x,highlightBlock:E,configure:function(e){f=y(f,e)},initHighlighting:N,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",N,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&A(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:T,registerAliases:A,requireLanguage:function(e){var n=T(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:I,inherit:y,addPlugin:function(e){o.push(e)}}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString="10.1.1";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);hljs.registerLanguage("php",function(){"use strict";return function(e){var r={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},t={className:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?[=]?/},{begin:/\?>/}]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]},i={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Throwable Traversable WeakReference Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{aliases:["php","php3","php4","php5","php6","php7"],case_insensitive:!0,keywords:i,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[t]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},t,{className:"keyword",begin:/\$this\b/},r,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",r,e.C_BLOCK_COMMENT_MODE,a,n]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},a,n]}}}());hljs.registerLanguage("nginx",function(){"use strict";return function(e){var n={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{/,end:/}/},{begin:"[\\$\\@]"+e.UNDERSCORE_IDENT_RE}]},a={endsWithParent:!0,keywords:{$pattern:"[a-z/_]+",literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},relevance:0,illegal:"=>",contains:[e.HASH_COMMENT_MODE,{className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[n]},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:"\\s\\^",end:"\\s|{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]*\\b",relevance:0},n]};return{name:"Nginx config",aliases:["nginxconf"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+"\\s+{",returnBegin:!0,end:"{",contains:[{className:"section",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+"\\s",end:";|{",returnBegin:!0,contains:[{className:"attribute",begin:e.UNDERSCORE_IDENT_RE,starts:a}],relevance:0}],illegal:"[^\\s\\}]"}}}());hljs.registerLanguage("csharp",function(){"use strict";return function(e){var n={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield",literal:"null false true"},i=e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},t=e.inherit(s,{illegal:/\n/}),l={className:"subst",begin:"{",end:"}",keywords:n},r=e.inherit(l,{illegal:/\n/}),c={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,r]},o={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},l]},g=e.inherit(o,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},r]});l.contains=[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],r.contains=[g,c,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];var d={variants:[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},E={begin:"<",end:">",contains:[{beginKeywords:"in out"},i]},_=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",b={begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:"</?",end:">"}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},d,a,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},i,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+_+"\\s+)+"+e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE,E],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[d,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},b]}}}());hljs.registerLanguage("perl",function(){"use strict";return function(e){var n={$pattern:/[\w.]+/,keyword:"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmget sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when"},t={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:n},s={begin:"->{",end:"}"},r={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},i=[e.BACKSLASH_ESCAPE,t,r],a=[r,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),s,{className:"string",contains:i,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return t.contains=a,s.contains=a,{name:"Perl",aliases:["pl","pm"],keywords:n,contains:a}}}());hljs.registerLanguage("swift",function(){"use strict";return function(e){var i={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},n=e.COMMENT("/\\*","\\*/",{contains:["self"]}),t={className:"subst",begin:/\\\(/,end:"\\)",keywords:i,contains:[]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}]},r={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0};return t.contains=[r],{name:"Swift",keywords:i,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},r,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin:/</,end:/>/},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:i,contains:["self",r,a,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:i,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)\\b"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}}());hljs.registerLanguage("makefile",function(){"use strict";return function(e){var i={className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%<?\^\+\*]/}]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,i]},a={className:"variable",begin:/\$\([\w-]+\s/,end:/\)/,keywords:{built_in:"subst patsubst strip findstring filter filter-out sort word wordlist firstword lastword dir notdir suffix basename addsuffix addprefix join wildcard realpath abspath error warning shell origin flavor foreach if or and call eval file value"},contains:[i]},r={begin:"^"+e.UNDERSCORE_IDENT_RE+"\\s*(?=[:+?]?=)"},s={className:"section",begin:/^[^\s]+:/,end:/$/,contains:[i]};return{name:"Makefile",aliases:["mk","mak"],keywords:{$pattern:/[\w-]+/,keyword:"define endef undefine ifdef ifndef ifeq ifneq else endif include -include sinclude override export unexport private vpath"},contains:[e.HASH_COMMENT_MODE,i,n,a,r,{className:"meta",begin:/^\.PHONY:/,end:/$/,keywords:{$pattern:/[\.\w]+/,"meta-keyword":".PHONY"}},s]}}}());hljs.registerLanguage("css",function(){"use strict";return function(e){var n={begin:/(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/,returnBegin:!0,end:";",endsWithParent:!0,contains:[{className:"attribute",begin:/\S/,end:":",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\w-]+\(/,returnBegin:!0,contains:[{className:"built_in",begin:/[\w-]+/},{begin:/\(/,end:/\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"#[0-9A-Fa-f]+"},{className:"meta",begin:"!important"}]}}]};return{name:"CSS",case_insensitive:!0,illegal:/[=\/|'\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/},{className:"selector-class",begin:/\.[A-Za-z0-9_-]+/},{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",illegal:/:/,returnBegin:!0,contains:[{className:"keyword",begin:/@\-?\w[\w]*(\-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:"and or not only",contains:[{begin:/[a-z-]+:/,className:"attribute"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},{begin:"{",end:"}",illegal:/\S/,contains:[e.C_BLOCK_COMMENT_MODE,n]}]}}}());hljs.registerLanguage("xml",function(){"use strict";return function(e){var n={className:"symbol",begin:"&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;"},a={begin:"\\s",contains:[{className:"meta-keyword",begin:"#?[a-z_][a-z1-9_-]+",illegal:"\\n"}]},s=e.inherit(a,{begin:"\\(",end:"\\)"}),t=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),i=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),c={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:"[A-Za-z0-9\\._:-]+",relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[n]},{begin:/'/,end:/'/,contains:[n]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"<![a-z]",end:">",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"<![a-z]",end:">",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:"<style(?=\\s|>)",end:">",keywords:{name:"style"},contains:[c],starts:{end:"</style>",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"<script(?=\\s|>)",end:">",keywords:{name:"script"},contains:[c],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:"</?",end:"/?>",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},c]}]}}}());hljs.registerLanguage("bash",function(){"use strict";return function(e){const s={};Object.assign(s,{className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{/,end:/\}/,contains:[{begin:/:-/,contains:[s]}]}]});const t={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,t]};t.contains.push(n);const a={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,s]},i=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b-?[a-z\._]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[i,e.SHEBANG(),c,a,e.HASH_COMMENT_MODE,n,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},s]}}}());hljs.registerLanguage("c-like",function(){"use strict";return function(e){function t(e){return"(?:"+e+")?"}var n="(decltype\\(auto\\)|"+t("[a-zA-Z_]\\w*::")+"[a-zA-Z_]\\w*"+t("<.*?>")+")",r={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},a={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},i={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(a,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},o={className:"title",begin:t("[a-zA-Z_]\\w*::")+e.IDENT_RE,relevance:0},c=t("[a-zA-Z_]\\w*::")+e.IDENT_RE+"\\s*\\(",l={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_t short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},d=[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i,a],_={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:l,contains:d.concat([{begin:/\(/,end:/\)/,keywords:l,contains:d.concat(["self"]),relevance:0}]),relevance:0},u={className:"function",begin:"("+n+"[\\*&\\s]+)+"+c,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:l,illegal:/[^\w\s\*&:<>]/,contains:[{begin:"decltype\\(auto\\)",keywords:l,relevance:0},{begin:c,returnBegin:!0,contains:[o],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r,{begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r]}]},r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],keywords:l,disableAutodetect:!0,illegal:"</",contains:[].concat(_,u,d,[s,{begin:"\\b(deque|list|queue|priority_queue|pair|stack|vector|map|set|bitset|multiset|multimap|unordered_map|unordered_set|unordered_multiset|unordered_multimap|array)\\s*<",end:">",keywords:l,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:l},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin:/</,end:/>/,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:s,strings:a,keywords:l}}}}());hljs.registerLanguage("coffeescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={keyword:e.concat(["then","unless","until","loop","by","when","and","or","is","isnt","not"]).filter((e=>n=>!e.includes(n))(["var","const","let","function","static"])).join(" "),literal:n.concat(["yes","no","on","off"]).join(" "),built_in:a.concat(["npm","print"]).join(" ")},i="[A-Za-z$_][0-9A-Za-z$_]*",s={className:"subst",begin:/#\{/,end:/}/,keywords:t},o=[r.BINARY_NUMBER_MODE,r.inherit(r.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'''/,end:/'''/,contains:[r.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[r.BACKSLASH_ESCAPE]},{begin:/"""/,end:/"""/,contains:[r.BACKSLASH_ESCAPE,s]},{begin:/"/,end:/"/,contains:[r.BACKSLASH_ESCAPE,s]}]},{className:"regexp",variants:[{begin:"///",end:"///",contains:[s,r.HASH_COMMENT_MODE]},{begin:"//[gim]{0,3}(?=\\W)",relevance:0},{begin:/\/(?![ *]).*?(?![\\]).\/[gim]{0,3}(?=\W)/}]},{begin:"@"+i},{subLanguage:"javascript",excludeBegin:!0,excludeEnd:!0,variants:[{begin:"```",end:"```"},{begin:"`",end:"`"}]}];s.contains=o;var c=r.inherit(r.TITLE_MODE,{begin:i}),l={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(o)}]};return{name:"CoffeeScript",aliases:["coffee","cson","iced"],keywords:t,illegal:/\/\*/,contains:o.concat([r.COMMENT("###","###"),r.HASH_COMMENT_MODE,{className:"function",begin:"^\\s*"+i+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[c,l]},{begin:/[:\(,=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[l]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[c]},c]},{begin:i+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}}());hljs.registerLanguage("ruby",function(){"use strict";return function(e){var n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",a={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},s={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},r=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^\\=begin","^\\=end",{contains:[s],relevance:10}),e.COMMENT("^__END__","\\n$")],c={className:"subst",begin:"#\\{",end:"}",keywords:a},t={className:"string",contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,c]})]}]},b={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:a},d=[t,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(r)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),b].concat(r)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[t,{begin:n}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:a},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(r),relevance:0}].concat(r);c.contains=d,b.contains=d;var g=[{begin:/^\s*=>/,starts:{end:"$",contains:d}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:d}}];return{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:a,illegal:/\/\*/,contains:r.concat(g).concat(d)}}}());hljs.registerLanguage("yaml",function(){"use strict";return function(e){var n="true false yes no null",a="[\\w#;/?:@&=+$,.~*\\'()[\\]]+",s={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]},i=e.inherit(s,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={end:",",endsWithParent:!0,excludeEnd:!0,contains:[],keywords:n,relevance:0},t={begin:"{",end:"}",contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]",contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type",begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"\\-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b"},t,g,s],c=[...b];return c.pop(),c.push(i),l.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml","YAML"],contains:b}}}());hljs.registerLanguage("d",function(){"use strict";return function(e){var a={$pattern:e.UNDERSCORE_IDENT_RE,keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},d="((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",n="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",t={className:"number",begin:"\\b"+d+"(L|u|U|Lu|LU|uL|UL)?",relevance:0},_={className:"number",begin:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+d+"(i|[fF]i|Li))",relevance:0},r={className:"string",begin:"'("+n+"|.)",end:"'",illegal:"."},i={className:"string",begin:'"',contains:[{begin:n,relevance:0}],end:'"[cwd]?'},s=e.COMMENT("\\/\\+","\\+\\/",{contains:["self"],relevance:10});return{name:"D",keywords:a,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:"string",begin:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',relevance:10},i,{className:"string",begin:'[rq]"',end:'"[cwd]?',relevance:5},{className:"string",begin:"`",end:"`[cwd]?"},{className:"string",begin:'q"\\{',end:'\\}"'},_,t,r,{className:"meta",begin:"^#!",end:"$",relevance:5},{className:"meta",begin:"#(line)",end:"$",relevance:5},{className:"keyword",begin:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}}());hljs.registerLanguage("properties",function(){"use strict";return function(e){var n="[ \\t\\f]*",t="("+n+"[:=]"+n+"|[ \\t\\f]+)",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",s={end:t,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\n"}]}};return{name:".properties",case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+"+t,returnBegin:!0,contains:[{className:"attr",begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",endsParent:!0,relevance:0}],starts:s},{begin:a+t,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:a,endsParent:!0,relevance:0}],starts:s},{className:"attr",relevance:0,begin:a+n+"$"}]}}}());hljs.registerLanguage("http",function(){"use strict";return function(e){var n="HTTP/[0-9\\.]+";return{name:"HTTP",aliases:["https"],illegal:"\\S",contains:[{begin:"^"+n,end:"$",contains:[{className:"number",begin:"\\b\\d{3}\\b"}]},{begin:"^[A-Z]+ (.*?) "+n+"$",returnBegin:!0,end:"$",contains:[{className:"string",begin:" ",end:" ",excludeBegin:!0,excludeEnd:!0},{begin:n},{className:"keyword",begin:"[A-Z]+"}]},{className:"attribute",begin:"^\\w",end:": ",excludeEnd:!0,illegal:"\\n|\\s|=",starts:{end:"$",relevance:0}},{begin:"\\n\\n",starts:{subLanguage:[],endsWithParent:!0}}]}}}());hljs.registerLanguage("haskell",function(){"use strict";return function(e){var n={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},i={className:"meta",begin:"{-#",end:"#-}"},a={className:"meta",begin:"^#",end:"$"},s={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},l={begin:"\\(",end:"\\)",illegal:'"',contains:[i,a,{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TITLE_MODE,{begin:"[_a-z][\\w']*"}),n]};return{name:"Haskell",aliases:["hs"],keywords:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",contains:[{beginKeywords:"module",end:"where",keywords:"module where",contains:[l,n],illegal:"\\W\\.|;"},{begin:"\\bimport\\b",end:"$",keywords:"import qualified as hiding",contains:[l,n],illegal:"\\W\\.|;"},{className:"class",begin:"^(\\s*)?(class|instance)\\b",end:"where",keywords:"class family instance where",contains:[s,l,n]},{className:"class",begin:"\\b(data|(new)?type)\\b",end:"$",keywords:"data family type newtype deriving",contains:[i,s,l,{begin:"{",end:"}",contains:l.contains},n]},{beginKeywords:"default",end:"$",contains:[s,l,n]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,n]},{begin:"\\bforeign\\b",end:"$",keywords:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",contains:[s,e.QUOTE_STRING_MODE,n]},{className:"meta",begin:"#!\\/usr\\/bin\\/env runhaskell",end:"$"},i,a,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,s,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),n,{begin:"->|<-"}]}}}());hljs.registerLanguage("handlebars",function(){"use strict";function e(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(n){const a={"builtin-name":"action bindattr collection component concat debugger each each-in get hash if in input link-to loc log lookup mut outlet partial query-params render template textarea unbound unless view with yield"},t=/\[.*?\]/,s=/[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/,i=e("(",/'.*?'/,"|",/".*?"/,"|",t,"|",s,"|",/\.|\//,")+"),r=e("(",t,"|",s,")(?==)"),l={begin:i,lexemes:/[\w.\/]+/},c=n.inherit(l,{keywords:{literal:"true false undefined null"}}),o={begin:/\(/,end:/\)/},m={className:"attr",begin:r,relevance:0,starts:{begin:/=/,end:/=/,starts:{contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,c,o]}}},d={contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,{begin:/as\s+\|/,keywords:{keyword:"as"},end:/\|/,contains:[{begin:/\w+/}]},m,c,o],returnEnd:!0},g=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/\)/})});o.contains=[g];const u=n.inherit(l,{keywords:a,className:"name",starts:n.inherit(d,{end:/}}/})}),b=n.inherit(l,{keywords:a,className:"name"}),h=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/}}/})});return{name:"Handlebars",aliases:["hbs","html.hbs","html.handlebars","htmlbars"],case_insensitive:!0,subLanguage:"xml",contains:[{begin:/\\\{\{/,skip:!0},{begin:/\\\\(?=\{\{)/,skip:!0},n.COMMENT(/\{\{!--/,/--\}\}/),n.COMMENT(/\{\{!/,/\}\}/),{className:"template-tag",begin:/\{\{\{\{(?!\/)/,end:/\}\}\}\}/,contains:[u],starts:{end:/\{\{\{\{\//,returnEnd:!0,subLanguage:"xml"}},{className:"template-tag",begin:/\{\{\{\{\//,end:/\}\}\}\}/,contains:[b]},{className:"template-tag",begin:/\{\{#/,end:/\}\}/,contains:[u]},{className:"template-tag",begin:/\{\{(?=else\}\})/,end:/\}\}/,keywords:"else"},{className:"template-tag",begin:/\{\{\//,end:/\}\}/,contains:[b]},{className:"template-variable",begin:/\{\{\{/,end:/\}\}\}/,contains:[h]},{className:"template-variable",begin:/\{\{/,end:/\}\}/,contains:[h]}]}}}());hljs.registerLanguage("rust",function(){"use strict";return function(e){var n="([ui](8|16|32|64|128|size)|f(32|64))?",t="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",keyword:"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield",literal:"true false Some None Ok Err",built_in:t},illegal:"</",contains:[e.C_LINE_COMMENT_MODE,e.COMMENT("/\\*","\\*/",{contains:["self"]}),e.inherit(e.QUOTE_STRING_MODE,{begin:/b?"/,illegal:null}),{className:"string",variants:[{begin:/r(#*)"(.|\n)*?"\1(?!#)/},{begin:/b?'\\?(x\w{2}|u\w{4}|U\w{8}|.)'/}]},{className:"symbol",begin:/'[a-zA-Z_][a-zA-Z0-9_]*/},{className:"number",variants:[{begin:"\\b0b([01_]+)"+n},{begin:"\\b0o([0-7_]+)"+n},{begin:"\\b0x([A-Fa-f0-9_]+)"+n},{begin:"\\b(\\d[\\d_]*(\\.[0-9_]+)?([eE][+-]?[0-9_]+)?)"+n}],relevance:0},{className:"function",beginKeywords:"fn",end:"(\\(|<)",excludeEnd:!0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"meta",begin:"#\\!?\\[",end:"\\]",contains:[{className:"meta-string",begin:/"/,end:/"/}]},{className:"class",beginKeywords:"type",end:";",contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{endsParent:!0})],illegal:"\\S"},{className:"class",beginKeywords:"trait enum struct union",end:"{",contains:[e.inherit(e.UNDERSCORE_TITLE_MODE,{endsParent:!0})],illegal:"[\\w\\d]"},{begin:e.IDENT_RE+"::",keywords:{built_in:t}},{begin:"->"}]}}}());hljs.registerLanguage("cpp",function(){"use strict";return function(e){var t=e.getLanguage("c-like").rawDefinition();return t.disableAutodetect=!1,t.name="C++",t.aliases=["cc","c++","h++","hpp","hh","hxx","cxx"],t}}());hljs.registerLanguage("ini",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(...n){return n.map(n=>e(n)).join("")}return function(a){var s={className:"number",relevance:0,variants:[{begin:/([\+\-]+)?[\d]+_[\d_]+/},{begin:a.NUMBER_RE}]},i=a.COMMENT();i.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];var t={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)}/}]},r={className:"literal",begin:/\bon|off|true|false|yes|no\b/},l={className:"string",contains:[a.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]},c={begin:/\[/,end:/\]/,contains:[i,r,t,l,s,"self"],relevance:0},g="("+[/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/].map(n=>e(n)).join("|")+")";return{name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[i,{className:"section",begin:/\[+/,end:/\]+/},{begin:n(g,"(\\s*\\.\\s*",g,")*",n("(?=",/\s*=\s*[^#\s]/,")")),className:"attr",starts:{end:/$/,contains:[i,c,r,t,l,s]}}]}}}());hljs.registerLanguage("objectivec",function(){"use strict";return function(e){var n=/[a-zA-Z@][a-zA-Z0-9_]*/,_={$pattern:n,keyword:"@interface @class @protocol @implementation"};return{name:"Objective-C",aliases:["mm","objc","obj-c"],keywords:{$pattern:n,keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},illegal:"</",contains:[{className:"built_in",begin:"\\b(AV|CA|CF|CG|CI|CL|CM|CN|CT|MK|MP|MTK|MTL|NS|SCN|SK|UI|WK|XC)\\w+"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.C_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"string",variants:[{begin:'@"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]}]},{className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+_.keyword.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:_,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}}());hljs.registerLanguage("apache",function(){"use strict";return function(e){var n={className:"number",begin:"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?"};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"section",begin:"</?",end:">",contains:[n,{className:"number",begin:":\\d{1,5}"},e.inherit(e.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{className:"meta",begin:"\\s\\[",end:"\\]$"},{className:"variable",begin:"[\\$%]\\{",end:"\\}",contains:["self",{className:"number",begin:"[\\$%]\\d+"}]},n,{className:"number",begin:"\\d+"},e.QUOTE_STRING_MODE]}}],illegal:/\S/}}}());hljs.registerLanguage("java",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(e){return a("(",e,")?")}function a(...n){return n.map(n=>e(n)).join("")}function s(...n){return"("+n.map(n=>e(n)).join("|")+")"}return function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",i={className:"meta",begin:"@[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},r=e=>a("[",e,"]+([",e,"_]*[",e,"]+)?"),c={className:"number",variants:[{begin:`\\b(0[bB]${r("01")})[lL]?`},{begin:`\\b(0${r("0-7")})[dDfFlL]?`},{begin:a(/\b0[xX]/,s(a(r("a-fA-F0-9"),/\./,r("a-fA-F0-9")),a(r("a-fA-F0-9"),/\.?/),a(/\./,r("a-fA-F0-9"))),/([pP][+-]?(\d+))?/,/[fFdDlL]?/)},{begin:a(/\b/,s(a(/\d*\./,r("\\d")),r("\\d")),/[eE][+-]?[\d]+[dDfF]?/)},{begin:a(/\b/,r(/\d/),n(/\.?/),n(r(/\d/)),/[dDfFlL]?/)}],relevance:0};return{name:"Java",aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},c,i]}}}());hljs.registerLanguage("x86asm",function(){"use strict";return function(s){return{name:"Intel x86 Assembly",case_insensitive:!0,keywords:{$pattern:"[.%]?"+s.IDENT_RE,keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0  xmm1  xmm2  xmm3  xmm4  xmm5  xmm6  xmm7  xmm8  xmm9 xmm10  xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0  ymm1  ymm2  ymm3  ymm4  ymm5  ymm6  ymm7  ymm8  ymm9 ymm10  ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0  zmm1  zmm2  zmm3  zmm4  zmm5  zmm6  zmm7  zmm8  zmm9 zmm10  zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__  __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__  __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},contains:[s.COMMENT(";","$",{relevance:0}),{className:"number",variants:[{begin:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",relevance:0},{begin:"\\$[0-9][0-9A-Fa-f]*",relevance:0},{begin:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{begin:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QUOTE_STRING_MODE,{className:"string",variants:[{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"[^\\\\]`"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{begin:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],relevance:0},{className:"subst",begin:"%[0-9]+",relevance:0},{className:"subst",begin:"%!S+",relevance:0},{className:"meta",begin:/^\s*\.[\w_-]+/}]}}}());hljs.registerLanguage("kotlin",function(){"use strict";return function(e){var n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},i={className:"subst",begin:"\\${",end:"}",contains:[e.C_NUMBER_MODE]},s={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},t={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[s,i]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,s,i]}]};i.contains.push(t);var r={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},l={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(t,{className:"meta-string"})]}]},c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),o={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=o;return d.variants[1].contains=[o],o.variants[1].contains=[d],{name:"Kotlin",aliases:["kt"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},a,r,l,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin:/</,end:/>/,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[o,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,r,l,t,e.C_NUMBER_MODE]},c]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin:/</,end:/>/,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},r,l]},t,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},{className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0}]}}}());hljs.registerLanguage("armasm",function(){"use strict";return function(s){const e={variants:[s.COMMENT("^[ \\t]*(?=#)","$",{relevance:0,excludeBegin:!0}),s.COMMENT("[;@]","$",{relevance:0}),s.C_LINE_COMMENT_MODE,s.C_BLOCK_COMMENT_MODE]};return{name:"ARM Assembly",case_insensitive:!0,aliases:["arm"],keywords:{$pattern:"\\.?"+s.IDENT_RE,meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?(?=\\s)"},e,s.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"[=#]\\w+"}],relevance:0}]}}}());hljs.registerLanguage("go",function(){"use strict";return function(e){var n={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{name:"Go",aliases:["golang"],keywords:n,illegal:"</",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"string",variants:[e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{begin:"`",end:"`"}]},{className:"number",variants:[{begin:e.C_NUMBER_RE+"[i]",relevance:1},e.C_NUMBER_MODE]},{begin:/:=/},{className:"function",beginKeywords:"func",end:"\\s*(\\{|$)",excludeEnd:!0,contains:[e.TITLE_MODE,{className:"params",begin:/\(/,end:/\)/,keywords:n,illegal:/["']/}]}]}}}());hljs.registerLanguage("diff",function(){"use strict";return function(e){return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,variants:[{begin:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{className:"comment",variants:[{begin:/Index: /,end:/$/},{begin:/={3,}/,end:/$/},{begin:/^\-{3}/,end:/$/},{begin:/^\*{3} /,end:/$/},{begin:/^\+{3}/,end:/$/},{begin:/^\*{15}$/}]},{className:"addition",begin:"^\\+",end:"$"},{className:"deletion",begin:"^\\-",end:"$"},{className:"addition",begin:"^\\!",end:"$"}]}}}());hljs.registerLanguage("python",function(){"use strict";return function(e){var n={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},a={className:"meta",begin:/^(>>>|\.\.\.) /},i={className:"subst",begin:/\{/,end:/\}/,keywords:n,illegal:/#/},s={begin:/\{\{/,relevance:0},r={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,s,i]},{begin:/(fr|rf|f)"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,i]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},l={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},t={className:"params",variants:[{begin:/\(\s*\)/,skip:!0,className:null},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:["self",a,l,r,e.HASH_COMMENT_MODE]}]};return i.contains=[r,l,a],{name:"Python",aliases:["py","gyp","ipython"],keywords:n,illegal:/(<\/|->|\?)|=>/,contains:[a,l,{beginKeywords:"if",relevance:0},r,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,t,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}}());hljs.registerLanguage("shell",function(){"use strict";return function(s){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}}());hljs.registerLanguage("scala",function(){"use strict";return function(e){var n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},a={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},s={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},t={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},i={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},t]},l={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[t]};return{name:"Scala",keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},s,l,i,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}}());hljs.registerLanguage("julia",function(){"use strict";return function(e){var r="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",t={$pattern:r,keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},a={keywords:t,illegal:/<\//},n={className:"subst",begin:/\$\(/,end:/\)/,keywords:t},o={className:"variable",begin:"\\$"+r},i={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],variants:[{begin:/\w*"""/,end:/"""\w*/,relevance:10},{begin:/\w*"/,end:/"\w*/}]},l={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],begin:"`",end:"`"},s={className:"meta",begin:"@"+r};return a.name="Julia",a.contains=[{className:"number",begin:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,l,s,{className:"comment",variants:[{begin:"#=",end:"=#",relevance:10},{begin:"#",end:"$"}]},e.HASH_COMMENT_MODE,{className:"keyword",begin:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{begin:/<:/}],n.contains=a.contains,a}}());hljs.registerLanguage("php-template",function(){"use strict";return function(n){return{name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}}}());hljs.registerLanguage("scss",function(){"use strict";return function(e){var t={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},i={className:"number",begin:"#[0-9A-Fa-f]+"};return e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"\\#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},{className:"selector-attr",begin:"\\[",end:"\\]",illegal:"$"},{className:"selector-tag",begin:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",relevance:0},{className:"selector-pseudo",begin:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{className:"selector-pseudo",begin:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},t,{className:"attribute",begin:"\\b(src|z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",illegal:"[^\\s]"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[t,i,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"meta",begin:"!important"}]},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",returnBegin:!0,keywords:"and or not only",contains:[{begin:"@[a-z-]+",className:"keyword"},t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,e.CSS_NUMBER_MODE]}]}}}());hljs.registerLanguage("r",function(){"use strict";return function(e){var n="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{name:"R",contains:[e.HASH_COMMENT_MODE,{begin:n,keywords:{$pattern:n,keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{className:"number",begin:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{className:"number",begin:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{className:"number",begin:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{begin:"`",end:"`",relevance:0},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'"',end:'"'},{begin:"'",end:"'"}]}]}}}());hljs.registerLanguage("sql",function(){"use strict";return function(e){var t=e.COMMENT("--","$");return{name:"SQL",case_insensitive:!0,illegal:/[<>{}*]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",end:/;/,endsWithParent:!0,keywords:{$pattern:/[\w\.]+/,keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:"`",end:"`"},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]}}}());hljs.registerLanguage("c",function(){"use strict";return function(e){var n=e.getLanguage("c-like").rawDefinition();return n.name="C",n.aliases=["c","h"],n}}());hljs.registerLanguage("json",function(){"use strict";return function(n){var e={literal:"true false null"},i=[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],t=[n.QUOTE_STRING_MODE,n.C_NUMBER_MODE],a={end:",",endsWithParent:!0,excludeEnd:!0,contains:t,keywords:e},l={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[n.BACKSLASH_ESCAPE],illegal:"\\n"},n.inherit(a,{begin:/:/})].concat(i),illegal:"\\S"},s={begin:"\\[",end:"\\]",contains:[n.inherit(a)],illegal:"\\S"};return t.push(l,s),i.forEach((function(n){t.push(n)})),{name:"JSON",contains:t,keywords:e,illegal:"\\S"}}}());hljs.registerLanguage("python-repl",function(){"use strict";return function(n){return{aliases:["pycon"],contains:[{className:"meta",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}}}());hljs.registerLanguage("markdown",function(){"use strict";return function(n){const e={begin:"<",end:">",subLanguage:"xml",relevance:0},a={begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},i={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},s={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};i.contains.push(s),s.contains.push(i);var c=[e,a];return i.contains=i.contains.concat(c),s.contains=s.contains.concat(c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:c=c.concat(i,s)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:c}]}]},e,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:c,end:"$"},{className:"code",variants:[{begin:"(`{3,})(.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})(.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}}());hljs.registerLanguage("javascript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function s(e){return r("(?=",e,")")}function r(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(t){var i="[A-Za-z$_][0-9A-Za-z$_]*",c={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/},o={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.join(" "),literal:n.join(" "),built_in:a.join(" ")},l={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:t.C_NUMBER_RE+"n?"}],relevance:0},E={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]},d={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"xml"}},g={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"css"}},u={className:"string",begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE,E]};E.contains=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,l,t.REGEXP_MODE];var b=E.contains.concat([{begin:/\(/,end:/\)/,contains:["self"].concat(E.contains,[t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE])},t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE]),_={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:b};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:o,contains:[t.SHEBANG({binary:"node",relevance:5}),{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,t.C_LINE_COMMENT_MODE,t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:i+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),t.C_BLOCK_COMMENT_MODE,l,{begin:r(/[{,\n]\s*/,s(r(/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,i+"\\s*:"))),relevance:0,contains:[{className:"attr",begin:i+s("\\s*:"),relevance:0}]},{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+t.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:b}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:"</>"},{begin:c.begin,end:c.end}],subLanguage:"xml",contains:[{begin:c.begin,end:c.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[t.inherit(t.TITLE_MODE,{begin:i}),_],illegal:/\[|%/},{begin:/\$[(.]/},t.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},t.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0},{begin:"(get|set)\\s+(?="+i+"\\()",end:/{/,keywords:"get set",contains:[t.inherit(t.TITLE_MODE,{begin:i}),{begin:/\(\)/},_]}],illegal:/#(?!!)/}}}());hljs.registerLanguage("typescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.concat(["type","namespace","typedef","interface","public","private","protected","implements","declare","abstract","readonly"]).join(" "),literal:n.join(" "),built_in:a.concat(["any","void","number","boolean","string","object","never","enum"]).join(" ")},s={className:"meta",begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},i={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:r.C_NUMBER_RE+"n?"}],relevance:0},o={className:"subst",begin:"\\$\\{",end:"\\}",keywords:t,contains:[]},c={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"xml"}},l={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"css"}},E={className:"string",begin:"`",end:"`",contains:[r.BACKSLASH_ESCAPE,o]};o.contains=[r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,i,r.REGEXP_MODE];var d={begin:"\\(",end:/\)/,keywords:t,contains:["self",r.QUOTE_STRING_MODE,r.APOS_STRING_MODE,r.NUMBER_MODE]},u={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,s,d]};return{name:"TypeScript",aliases:["ts"],keywords:t,contains:[r.SHEBANG(),{className:"meta",begin:/^\s*['"]use strict['"]/},r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,i,{begin:"("+r.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,r.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+r.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:r.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:d.contains}]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[\{;]/,excludeEnd:!0,keywords:t,contains:["self",r.inherit(r.TITLE_MODE,{begin:"[A-Za-z$_][0-9A-Za-z$_]*"}),u],illegal:/%/,relevance:0},{beginKeywords:"constructor",end:/[\{;]/,excludeEnd:!0,contains:["self",u]},{begin:/module\./,keywords:{built_in:"module"},relevance:0},{beginKeywords:"module",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"},{begin:/\$[(.]/},{begin:"\\."+r.IDENT_RE,relevance:0},s,d]}}}());hljs.registerLanguage("plaintext",function(){"use strict";return function(t){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}}}());hljs.registerLanguage("less",function(){"use strict";return function(e){var n="([\\w-]+|@{[\\w-]+})",a=[],s=[],t=function(e){return{className:"string",begin:"~?"+e+".*?"+e}},r=function(e,n,a){return{className:e,begin:n,relevance:a}},i={begin:"\\(",end:"\\)",contains:s,relevance:0};s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t("'"),t('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},r("number","#[0-9A-Fa-f]+\\b"),i,r("variable","@@?[\\w-]+",10),r("variable","@{[\\w-]+}"),r("built_in","~?`[^`]*?`"),{className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0},{className:"meta",begin:"!important"});var c=s.concat({begin:"{",end:"}",contains:a}),l={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(s)},o={begin:n+"\\s*:",returnBegin:!0,end:"[;}]",relevance:0,contains:[{className:"attribute",begin:n,end:":",excludeEnd:!0,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]},g={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",returnEnd:!0,contains:s,relevance:0}},d={className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:c}},b={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:n,end:"{"}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,r("keyword","all\\b"),r("variable","@{[\\w-]+}"),r("selector-tag",n+"%?",0),r("selector-id","#"+n),r("selector-class","\\."+n,0),r("selector-tag","&",0),{className:"selector-attr",begin:"\\[",end:"\\]"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"\\(",end:"\\)",contains:c},{begin:"!important"}]};return a.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,d,o,b),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:a}}}());hljs.registerLanguage("lua",function(){"use strict";return function(e){var t={begin:"\\[=*\\[",end:"\\]=*\\]",contains:["self"]},a=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[","\\]=*\\]",{contains:[t],relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:a.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:a}].concat(a)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"\\[=*\\[",end:"\\]=*\\]",contains:[t],relevance:5}])}}}());
diff --git a/src/theme/index.hbs b/src/theme/index.hbs
new file mode 100644
index 0000000..e9e6cff
--- /dev/null
+++ b/src/theme/index.hbs
@@ -0,0 +1,306 @@
+<!DOCTYPE HTML>
+<html lang="{{ language }}" class="sidebar-visible no-js {{ default_theme }}">
+    <head>
+        <!-- Book generated using mdBook -->
+        <meta charset="UTF-8">
+        <title>{{ title }}</title>
+        {{#if is_print }}
+        <meta name="robots" content="noindex" />
+        {{/if}}
+        {{#if base_url}}
+        <base href="{{ base_url }}">
+        {{/if}}
+
+
+        <!-- Custom HTML head -->
+        {{> head}}
+
+        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
+        <meta name="description" content="{{ description }}">
+        <meta name="viewport" content="width=device-width, initial-scale=1">
+        <meta name="theme-color" content="#ffffff" />
+
+        {{#if favicon_svg}}
+        <link rel="icon" href="{{ path_to_root }}favicon.svg">
+        {{/if}}
+        {{#if favicon_png}}
+        <link rel="shortcut icon" href="{{ path_to_root }}favicon.png">
+        {{/if}}
+        <link rel="stylesheet" href="{{ path_to_root }}css/variables.css">
+        <link rel="stylesheet" href="{{ path_to_root }}css/general.css">
+        <link rel="stylesheet" href="{{ path_to_root }}css/chrome.css">
+        {{#if print_enable}}
+        <link rel="stylesheet" href="{{ path_to_root }}css/print.css" media="print">
+        {{/if}}
+
+        <!-- Fonts -->
+        <link rel="stylesheet" href="{{ path_to_root }}FontAwesome/css/font-awesome.css">
+        {{#if copy_fonts}}
+        <link rel="stylesheet" href="{{ path_to_root }}fonts/fonts.css">
+        {{/if}}
+
+        <!-- Highlight.js Stylesheets -->
+        <link rel="stylesheet" href="{{ path_to_root }}highlight.css">
+        <link rel="stylesheet" href="{{ path_to_root }}tomorrow-night.css">
+        <link rel="stylesheet" href="{{ path_to_root }}ayu-highlight.css">
+
+        <!-- Custom theme stylesheets -->
+        {{#each additional_css}}
+        <link rel="stylesheet" href="{{ ../path_to_root }}{{ this }}">
+        {{/each}}
+
+        {{#if mathjax_support}}
+        <!-- MathJax -->
+        <script async type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
+        {{/if}}
+    </head>
+    <body>
+        <!-- Provide site root to javascript -->
+        <script type="text/javascript">
+            var path_to_root = "{{ path_to_root }}";
+            var default_theme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "{{ preferred_dark_theme }}" : "{{ default_theme }}";
+        </script>
+
+        <!-- Work around some values being stored in localStorage wrapped in quotes -->
+        <script type="text/javascript">
+            try {
+                var theme = localStorage.getItem('mdbook-theme');
+                var sidebar = localStorage.getItem('mdbook-sidebar');
+
+                if (theme.startsWith('"') && theme.endsWith('"')) {
+                    localStorage.setItem('mdbook-theme', theme.slice(1, theme.length - 1));
+                }
+
+                if (sidebar.startsWith('"') && sidebar.endsWith('"')) {
+                    localStorage.setItem('mdbook-sidebar', sidebar.slice(1, sidebar.length - 1));
+                }
+            } catch (e) { }
+        </script>
+
+        <!-- Set the theme before any content is loaded, prevents flash -->
+        <script type="text/javascript">
+            var theme;
+            try { theme = localStorage.getItem('mdbook-theme'); } catch(e) { }
+            if (theme === null || theme === undefined) { theme = default_theme; }
+            var html = document.querySelector('html');
+            html.classList.remove('no-js')
+            html.classList.remove('{{ default_theme }}')
+            html.classList.add(theme);
+            html.classList.add('js');
+        </script>
+
+        <!-- Hide / unhide sidebar before it is displayed -->
+        <script type="text/javascript">
+            var html = document.querySelector('html');
+            var sidebar = 'hidden';
+            if (document.body.clientWidth >= 1080) {
+                try { sidebar = localStorage.getItem('mdbook-sidebar'); } catch(e) { }
+                sidebar = sidebar || 'visible';
+            }
+            html.classList.remove('sidebar-visible');
+            html.classList.add("sidebar-" + sidebar);
+        </script>
+
+        <nav id="sidebar" class="sidebar" aria-label="Table of contents">
+            <div class="sidebar-scrollbox">
+                {{#toc}}{{/toc}}
+            </div>
+            <div id="sidebar-resize-handle" class="sidebar-resize-handle"></div>
+        </nav>
+
+        <div id="page-wrapper" class="page-wrapper">
+
+            <div class="page">
+                {{> header}}
+                <div id="menu-bar-hover-placeholder"></div>
+                <div id="menu-bar" class="menu-bar sticky bordered">
+                    <div class="left-buttons">
+                        <button id="sidebar-toggle" class="icon-button" type="button" title="Toggle Table of Contents" aria-label="Toggle Table of Contents" aria-controls="sidebar">
+                            <i class="fa fa-bars"></i>
+                        </button>
+                        <button id="theme-toggle" class="icon-button" type="button" title="Change theme" aria-label="Change theme" aria-haspopup="true" aria-expanded="false" aria-controls="theme-list">
+                            <i class="fa fa-paint-brush"></i>
+                        </button>
+                        <ul id="theme-list" class="theme-popup" aria-label="Themes" role="menu">
+                            <li role="none"><button role="menuitem" class="theme" id="light">{{ theme_option "Light" }}</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="rust">{{ theme_option "Rust" }}</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="coal">{{ theme_option "Coal" }}</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="navy">{{ theme_option "Navy" }}</button></li>
+                            <li role="none"><button role="menuitem" class="theme" id="ayu">{{ theme_option "Ayu" }}</button></li>
+                        </ul>
+                        {{#if search_enabled}}
+                        <button id="search-toggle" class="icon-button" type="button" title="Search. (Shortkey: s)" aria-label="Toggle Searchbar" aria-expanded="false" aria-keyshortcuts="S" aria-controls="searchbar">
+                            <i class="fa fa-search"></i>
+                        </button>
+                        {{/if}}
+                    </div>
+
+                    <h1 class="menu-title">{{ book_title }}</h1>
+
+                    <div class="right-buttons">
+                        {{#if print_enable}}
+                        <a href="{{ path_to_root }}print.html" title="Print this book" aria-label="Print this book">
+                            <i id="print-button" class="fa fa-print"></i>
+                        </a>
+                        {{/if}}
+                        {{#if git_repository_url}}
+                        <a href="{{git_repository_url}}" title="Git repository" aria-label="Git repository">
+                            <i id="git-repository-button" class="fa {{git_repository_icon}}"></i>
+                        </a>
+                        {{/if}}
+                    </div>
+                </div>
+
+                {{#if search_enabled}}
+                <div id="search-wrapper" class="hidden">
+                    <form id="searchbar-outer" class="searchbar-outer">
+                        <input type="search" name="search" id="searchbar" name="searchbar" placeholder="Search this book ..." aria-controls="searchresults-outer" aria-describedby="searchresults-header">
+                    </form>
+                    <div id="searchresults-outer" class="searchresults-outer hidden">
+                        <div id="searchresults-header" class="searchresults-header"></div>
+                        <ul id="searchresults">
+                        </ul>
+                    </div>
+                </div>
+                {{/if}}
+
+                <!-- Apply ARIA attributes after the sidebar and the sidebar toggle button are added to the DOM -->
+                <script type="text/javascript">
+                    document.getElementById('sidebar-toggle').setAttribute('aria-expanded', sidebar === 'visible');
+                    document.getElementById('sidebar').setAttribute('aria-hidden', sidebar !== 'visible');
+                    Array.from(document.querySelectorAll('#sidebar a')).forEach(function(link) {
+                        link.setAttribute('tabIndex', sidebar === 'visible' ? 0 : -1);
+                    });
+                </script>
+
+                <div id="content" class="content">
+                    <main>
+                        {{{ content }}}
+                    </main>
+
+                    <nav class="nav-wrapper" aria-label="Page navigation">
+                        <!-- Mobile navigation buttons -->
+                        {{#previous}}
+                            <a rel="prev" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                                <i class="fa fa-angle-left"></i>
+                            </a>
+                        {{/previous}}
+
+                        {{#next}}
+                            <a rel="next" href="{{ path_to_root }}{{link}}" class="mobile-nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                                <i class="fa fa-angle-right"></i>
+                            </a>
+                        {{/next}}
+
+                        <div style="clear: both"></div>
+                    </nav>
+                </div>
+            </div>
+
+            <nav class="nav-wide-wrapper" aria-label="Page navigation">
+                {{#previous}}
+                    <a rel="prev" href="{{ path_to_root }}{{link}}" class="nav-chapters previous" title="Previous chapter" aria-label="Previous chapter" aria-keyshortcuts="Left">
+                        <i class="fa fa-angle-left"></i>
+                    </a>
+                {{/previous}}
+
+                {{#next}}
+                    <a rel="next" href="{{ path_to_root }}{{link}}" class="nav-chapters next" title="Next chapter" aria-label="Next chapter" aria-keyshortcuts="Right">
+                        <i class="fa fa-angle-right"></i>
+                    </a>
+                {{/next}}
+            </nav>
+
+        </div>
+
+        {{#if livereload}}
+        <!-- Livereload script (if served using the cli tool) -->
+        <script type="text/javascript">
+            var socket = new WebSocket("{{{livereload}}}");
+            socket.onmessage = function (event) {
+                if (event.data === "reload") {
+                    socket.close();
+                    location.reload();
+                }
+            };
+
+            window.onbeforeunload = function() {
+                socket.close();
+            }
+        </script>
+        {{/if}}
+
+        {{#if google_analytics}}
+        <!-- Google Analytics Tag -->
+        <script type="text/javascript">
+            var localAddrs = ["localhost", "127.0.0.1", ""];
+
+            // make sure we don't activate google analytics if the developer is
+            // inspecting the book locally...
+            if (localAddrs.indexOf(document.location.hostname) === -1) {
+                (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+                (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+                m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+                })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
+
+                ga('create', '{{google_analytics}}', 'auto');
+                ga('send', 'pageview');
+            }
+        </script>
+        {{/if}}
+
+        {{#if playground_line_numbers}}
+        <script type="text/javascript">
+            window.playground_line_numbers = true;
+        </script>
+        {{/if}}
+
+        {{#if playground_copyable}}
+        <script type="text/javascript">
+            window.playground_copyable = true;
+        </script>
+        {{/if}}
+
+        {{#if playground_js}}
+        <script src="{{ path_to_root }}ace.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}editor.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}mode-rust.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}theme-dawn.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}theme-tomorrow_night.js" type="text/javascript" charset="utf-8"></script>
+        {{/if}}
+
+        {{#if search_js}}
+        <script src="{{ path_to_root }}elasticlunr.min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}mark.min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}searcher.js" type="text/javascript" charset="utf-8"></script>
+        {{/if}}
+
+        <script src="{{ path_to_root }}clipboard.min.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}highlight.js" type="text/javascript" charset="utf-8"></script>
+        <script src="{{ path_to_root }}book.js" type="text/javascript" charset="utf-8"></script>
+
+        <!-- Custom JS scripts -->
+        {{#each additional_js}}
+        <script type="text/javascript" src="{{ ../path_to_root }}{{this}}"></script>
+        {{/each}}
+
+        {{#if is_print}}
+        {{#if mathjax_support}}
+        <script type="text/javascript">
+        window.addEventListener('load', function() {
+            MathJax.Hub.Register.StartupHook('End', function() {
+                window.setTimeout(window.print, 100);
+            });
+        });
+        </script>
+        {{else}}
+        <script type="text/javascript">
+        window.addEventListener('load', function() {
+            window.setTimeout(window.print, 100);
+        });
+        </script>
+        {{/if}}
+        {{/if}}
+
+    </body>
+</html>

From 48df25862d6c4ce777a119b7b7b5908521cb41fb Mon Sep 17 00:00:00 2001
From: Victor Dudochkin <dudochkin.victor@gmail.com>
Date: Tue, 30 Mar 2021 03:14:01 +0700
Subject: [PATCH 2/4] branch fix

---
 .github/workflows/publish_gh_pages.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/publish_gh_pages.yml b/.github/workflows/publish_gh_pages.yml
index f1d443d..9e35c42 100644
--- a/.github/workflows/publish_gh_pages.yml
+++ b/.github/workflows/publish_gh_pages.yml
@@ -7,7 +7,7 @@ name: github pages
 on:
   push:
     branches:
-      - pages
+      - docs
 
 jobs:
   deploy:

From be475485764f59a6e385abba3901f85d504cbc42 Mon Sep 17 00:00:00 2001
From: Victor Dudochkin <dudochkin.victor@gmail.com>
Date: Mon, 12 Apr 2021 10:53:12 +0700
Subject: [PATCH 3/4] Cleanup

---
 ...publish_gh_pages.yml => documentation.yml} |   2 +-
 src/01-index.md                               |  22 +
 src/02-cairolib.md                            |  39 ++
 src/03-cairodefinitions.md                    |  49 ++
 src/04-cairobackends.md                       | 276 +++++++++++
 src/05-basicdrawing.md                        | 428 ++++++++++++++++++
 src/06-shapesfills.md                         | 331 ++++++++++++++
 src/07-gradients.md                           | 244 ++++++++++
 src/08-transparency.md                        | 361 +++++++++++++++
 src/09-compositing.md                         | 153 +++++++
 src/10-clippingmasking.md                     | 390 ++++++++++++++++
 src/11-transformations.md                     | 416 +++++++++++++++++
 src/12-cairotext.md                           | 247 ++++++++++
 src/13-cairoimages.md                         | 365 +++++++++++++++
 src/14-root.md                                | 329 ++++++++++++++
 15 files changed, 3651 insertions(+), 1 deletion(-)
 rename .github/workflows/{publish_gh_pages.yml => documentation.yml} (95%)
 create mode 100644 src/01-index.md
 create mode 100644 src/02-cairolib.md
 create mode 100644 src/03-cairodefinitions.md
 create mode 100644 src/04-cairobackends.md
 create mode 100644 src/05-basicdrawing.md
 create mode 100644 src/06-shapesfills.md
 create mode 100644 src/07-gradients.md
 create mode 100644 src/08-transparency.md
 create mode 100644 src/09-compositing.md
 create mode 100644 src/10-clippingmasking.md
 create mode 100644 src/11-transformations.md
 create mode 100644 src/12-cairotext.md
 create mode 100644 src/13-cairoimages.md
 create mode 100644 src/14-root.md

diff --git a/.github/workflows/publish_gh_pages.yml b/.github/workflows/documentation.yml
similarity index 95%
rename from .github/workflows/publish_gh_pages.yml
rename to .github/workflows/documentation.yml
index 9e35c42..ea331d1 100644
--- a/.github/workflows/publish_gh_pages.yml
+++ b/.github/workflows/documentation.yml
@@ -2,7 +2,7 @@
 
 # On every push this script is executed
 
-name: github pages
+name: Publish documentation
 
 on:
   push:
diff --git a/src/01-index.md b/src/01-index.md
new file mode 100644
index 0000000..fc9f517
--- /dev/null
+++ b/src/01-index.md
@@ -0,0 +1,22 @@
+# Cairo graphics tutorial
+last modified July 13, 2020
+
+This is Cairo graphics tutorial. The tutorial will teach you the basics of graphics programming in Cairo with the C programming language. This tutorial is for beginners and intermediate developers.
+
+## Table of contents
+- Introduction
+- Cairo definitions
+- Cairo backends
+- Basic drawing
+- Shapes and fills
+- Gradients
+- Transparency
+- Compositing
+- Clipping and masking
+- Transformations
+- Text
+- Images in Cairo
+- Root window
+
+## Cairo
+Cairo is a library for creating 2D vector graphics. It is written in the C programming language. There are bindings for other computer languages. Python, Perl, C++, C# or Java. Cairo is a multiplatform library. It works on Linux, BSDs, OSX.
\ No newline at end of file
diff --git a/src/02-cairolib.md b/src/02-cairolib.md
new file mode 100644
index 0000000..13e64e6
--- /dev/null
+++ b/src/02-cairolib.md
@@ -0,0 +1,39 @@
+# The Cairo graphics library
+last modified July 13, 2020
+
+Welcome to the Cairo graphics tutorial. This tutorial will teach you basics and some advanced topics of the Cairo 2D vector drawing library. In most examples we will use the GTK+ programming library. This tutorial is done in C programming language.
+
+## 2D Vector Graphics
+There are two different computer graphics. Vector and raster graphics. Raster graphics represents images as a collection of pixels. Vector graphics is the use of geometrical primitives such as points, lines, curves or polygons to represent images. These primitives are created using mathematical equations.
+
+Both types of computer graphics have advantages and disadvantages. The advantages of vector graphics over raster are:
+
+smaller size
+ability to zoom indefinitely
+moving, scaling, filling or rotating does not degrade the quality of an image
+
+## Cairo
+Cairo is a library for creating 2D vector graphics. It is written in the C programming language. Bindings for other computer languages exist. Python, Perl, C++, C#, Java. Cairo is a multiplatform library, it works on Linux, BSDs, and Mac OS.
+
+Cairo supports various backends.
+
+- X Window System
+- Win32 GDI
+- Mac OS X Quartz
+- PNG
+- PDF
+- PostScript
+- SVG
+
+This means that we can use the library to draw on windows on Linux/BSDs, Windows, Mac OS and we can use the library to create PNG images, PDF files, PostScript files, and SVG files.
+
+We can compare the cairo library to the GDI+ library on Windows OS and the Quartz 2D on Mac OS. Cairo is an open source software library. From version 2.8, the cairo library is part of the GTK+ system.
+
+## Compiling examples
+The examples are created in the C programming language. We use the GNU C compiler to compile them.
+
+```bash
+gcc example.c -o example `pkg-config --cflags --libs gtk+-3.0` 
+```
+
+Note that the order of compiling options is important.
\ No newline at end of file
diff --git a/src/03-cairodefinitions.md b/src/03-cairodefinitions.md
new file mode 100644
index 0000000..19144c5
--- /dev/null
+++ b/src/03-cairodefinitions.md
@@ -0,0 +1,49 @@
+# Cairo definitions
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will provide some useful definitions for the Cairo graphics library. This will help us better understand the Cairo drawing model.
+
+## Context
+Drawing in Cairo is done via the Context. The Cairo context holds all of the graphics state parameters that describe how drawing is to be done. This includes information such as line width, colour, the surface to draw to, and many other things. This allows the actual drawing functions to take fewer arguments to simplify the interface.
+
+All drawing with Cairo is always done to a cairo_t object. A Cairo context is tied to a specific surface. A PDF, SVG, PNG, GtkWindow etc.
+
+## Path
+A path is made up of one or more lines. These lines are connected by two or more anchor points. Paths can be made up of straight lines and curves. There are two kinds of paths. Open and closed paths. In a closed path, starting and ending points meet. In an open path, starting and ending point do not meet.
+
+In Cairo, we start with an empty path. First we define a path and then we make them visible by stroking and filling them. One important note. After each cairo_stroke() or cairo_fill() function calls, the path is emptied. We have to define a new path.
+
+A path is made of subpaths.
+
+## Source
+The source is the paint we use in drawing. We can compare the source to a pen or ink that we will use to draw the outlines and fill the shapes. There are four kinds of basic sources: colors, gradients, patterns, and images.
+
+## Surface
+A surface is a destination that we are drawing to. We can render documents using the PDF or PostScript surfaces, directly draw to a platform via the Xlib and Win32 surfaces.
+
+The documentation mentions the following surfaces:
+
+```cpp
+typedef enum _cairo_surface_type {
+  CAIRO_SURFACE_TYPE_IMAGE,
+  CAIRO_SURFACE_TYPE_PDF,
+  CAIRO_SURFACE_TYPE_PS,
+  CAIRO_SURFACE_TYPE_XLIB,
+  CAIRO_SURFACE_TYPE_XCB,
+  CAIRO_SURFACE_TYPE_GLITZ,
+  CAIRO_SURFACE_TYPE_QUARTZ,
+  CAIRO_SURFACE_TYPE_WIN32,
+  CAIRO_SURFACE_TYPE_BEOS,
+  CAIRO_SURFACE_TYPE_DIRECTFB,
+  CAIRO_SURFACE_TYPE_SVG,
+  CAIRO_SURFACE_TYPE_OS2
+} cairo_surface_type_t;
+```
+
+## Mask
+Before the source is applied to the surface, it is filtered first. The mask is used as a filter. The mask determines, where the source is applied and where not. Opaque parts of the mask allow to copy the source. Transparent parts do not let to copy the source to the surface.
+
+## Pattern
+A cairo pattern represents a source when drawing onto a surface. In cairo, a pattern is something that you can read from that is used as the source or mask of a drawing operation. Patterns in cairo can be solid, surface-based or gradients patterns.
+
+In this chapter of the Cairo tutorial, we have given some basic definitions.
\ No newline at end of file
diff --git a/src/04-cairobackends.md b/src/04-cairobackends.md
new file mode 100644
index 0000000..caa889b
--- /dev/null
+++ b/src/04-cairobackends.md
@@ -0,0 +1,276 @@
+# Cairo backends
+last modified July 13, 2020
+
+The Cairo library supports various backends. In this section of the Cairo graphics tutorial, we will use Cairo to create a PNG image, PDF file, SVG file and we will draw on a GTK window.
+
+## PNG image
+In the first example, we will create a PNG image.
+
+```cpp
+#include <cairo.h>
+
+int main(void)
+{
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
+  cr = cairo_create(surface);
+
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size(cr, 40.0);
+
+  cairo_move_to(cr, 10.0, 50.0);
+  cairo_show_text(cr, "Disziplin ist Macht.");
+
+  cairo_surface_write_to_png(surface, "image.png");
+
+  cairo_destroy(cr);
+  cairo_surface_destroy(surface);
+
+  return 0;
+}
+```
+This example is a small console application that will create a PNG image.
+
+```cpp
+#include <cairo.h>
+```
+In this header file, we will find declarations of our functions and constants.
+
+```cpp
+cairo_surface_t *surface;
+cairo_t *cr;
+```
+Here we declare a surface and a Cairo context.
+
+```cpp
+surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 390, 60);
+cr = cairo_create(surface);
+```
+We create a surface and a Cairo context. The surface is an 390x60 px image.
+
+```cpp
+cairo_set_source_rgb(cr, 0, 0, 0);
+```
+We will draw in black ink.
+
+```cpp
+cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+    CAIRO_FONT_WEIGHT_NORMAL);
+cairo_set_font_size(cr, 40.0);
+```
+We choose a font type and set its size.
+
+```cpp
+cairo_move_to(cr, 10.0, 50.0);
+cairo_show_text(cr, "Disziplin ist Macht.");
+```
+We move to a (10.0, 50.0) position within the image and draw the text.
+
+```cpp
+cairo_surface_write_to_png(surface, "image.png");
+```
+This function call creates the PNG image.
+
+```cpp
+cairo_destroy(cr);
+cairo_surface_destroy(surface);
+```
+In the end, we clean the resources.
+
+## PDF file
+In the second example, we will use the Cairo library to create a simple PDF file.
+
+```cpp
+#include <cairo.h>
+#include <cairo-pdf.h>
+
+int main(void) 
+{
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
+  cr = cairo_create(surface);
+
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_select_font_face (cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size (cr, 40.0);
+
+  cairo_move_to(cr, 10.0, 50.0);
+  cairo_show_text(cr, "Disziplin ist Macht.");
+
+  cairo_show_page(cr);
+
+  cairo_surface_destroy(surface);
+  cairo_destroy(cr);
+
+  return 0;
+}
+```
+We must open the PDF file in a PDF viewer. Linux users can use KPDF or Evince viewers.
+
+```cpp
+surface = cairo_pdf_surface_create("pdffile.pdf", 504, 648);
+```
+To render a PDF file, we must create a PDF surface using the cairo_pdf_surface_create() function call. The size of the PDF file is specified in points, which is a standard in typesetting.
+
+```cpp
+cairo_show_page(cr);
+```
+The cairo_show_page() finishes rendering of the PDF file.
+
+(PDF file in Evince) Figure: PDF file in Evince
+
+## SVG file
+The next example creates a simple SVG (Scalable Vector Graphics) file. The SVG is one of the hottest technologies these days.
+
+```cpp
+#include <cairo.h>
+#include <cairo-svg.h> 
+ 
+int main(void) 
+{
+  cairo_surface_t *surface;
+  cairo_t *cr;
+
+  surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
+  cr = cairo_create(surface);
+
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size(cr, 40.0);
+
+  cairo_move_to(cr, 10.0, 50.0);
+  cairo_show_text(cr, "Disziplin ist Macht.");
+
+  cairo_surface_destroy(surface);
+  cairo_destroy(cr);
+
+  return 0;
+}
+```
+We can use Firefox, Opera or Inkscape programs to open the svgfile.svg file.
+
+```cpp
+surface = cairo_svg_surface_create("svgfile.svg", 390, 60);
+```
+To create a SVG file in Cairo, we must create a svg surface using the cairo_svg_surface_create() function call.
+
+```cpp
+cr = cairo_create(surface);
+```
+A Cairo context is created from a SVG surface.
+
+The Rest of the code is identical to the previous examples.
+
+(SVG file in Chrome) SVG file in Chrome
+
+## GTK Window
+In the last example, we will draw on the GTK window. This backend will be used throughout the rest of the tutorial.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size(cr, 40.0);
+
+  cairo_move_to(cr, 10.0, 50.0);
+  cairo_show_text(cr, "Disziplin ist Macht.");    
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 400, 90); 
+  gtk_window_set_title(GTK_WINDOW(window), "GTK window");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+The example pops up a centered GTK window, on which we draw the "Disziplin ist Macht" text.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+```
+We include the necessary Cairo and GTK headers.
+
+```cpp
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);
+
+  return FALSE;
+}
+We delegate the actual drawing to the do_drawing() function. The parameter sent is the Cairo context.
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size(cr, 40.0);
+
+  cairo_move_to(cr, 10.0, 50.0);
+  cairo_show_text(cr, "Disziplin ist Macht.");    
+}
+```
+The Cairo functions perform the drawing.
+
+```cpp
+darea = gtk_drawing_area_new();
+gtk_container_add(GTK_CONTAINER(window), darea);
+```
+We create a GtkDrawingArea widget and add it to the container window. It is used for custom drawing.
+
+```cpp
+g_signal_connect(G_OBJECT(darea), "draw", 
+    G_CALLBACK(on_draw_event), NULL); 
+```
+When the GtkDrawingArea widget needs to be redrawn, it emits the draw signal. We connect that signal to the on_draw_event() callback.
+
+(GTK window) Figure: GTK window
+
+In this chapter we have covered supported Cairo backends.
\ No newline at end of file
diff --git a/src/05-basicdrawing.md b/src/05-basicdrawing.md
new file mode 100644
index 0000000..dbb48e7
--- /dev/null
+++ b/src/05-basicdrawing.md
@@ -0,0 +1,428 @@
+# Basic drawing in Cairo
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will draw some basic primitives. We will draw simple lines, use fill and stroke operations, we will talk about dashes, line caps and line joins.
+
+## Lines
+Lines are very basic vector objects. To draw a line, we use two function calls. The starting point is specified with the cairo_move_to() call. The ending point of a line is specified with the cairo_line_to() call.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+struct {
+  int count;
+  double coordx[100];
+  double coordy[100];
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{
+  do_drawing(cr);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_set_line_width(cr, 0.5);
+
+  int i, j;
+  for (i = 0; i <= glob.count - 1; i++ ) {
+      for (j = 0; j <= glob.count - 1; j++ ) {
+          cairo_move_to(cr, glob.coordx[i], glob.coordy[i]);
+          cairo_line_to(cr, glob.coordx[j], glob.coordy[j]);
+      }
+  }
+
+  glob.count = 0;
+  cairo_stroke(cr);    
+}
+
+static gboolean clicked(GtkWidget *widget, GdkEventButton *event,
+    gpointer user_data)
+{
+    if (event->button == 1) {
+        glob.coordx[glob.count] = event->x;
+        glob.coordy[glob.count++] = event->y;
+    }
+
+    if (event->button == 3) {
+        gtk_widget_queue_draw(widget);
+    }
+
+    return TRUE;
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+  
+  glob.count = 0;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+ 
+  gtk_widget_add_events(window, GDK_BUTTON_PRESS_MASK);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);  
+    
+  g_signal_connect(window, "button-press-event", 
+      G_CALLBACK(clicked), NULL);
+ 
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); 
+  gtk_window_set_title(GTK_WINDOW(window), "Lines");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+In our example, we click randomly on a window with a left mouse button. Each click is stored in an array. When we right click on the window, all points are connected with every point in the array. This way, we can create some interesting objects. Right clicking on the drawn object clears the window, and we can click another object.
+
+```cpp
+cairo_set_source_rgb(cr, 0, 0, 0);
+cairo_set_line_width (cr, 0.5);
+The lines will be drawn in black ink and will be 0.5 points wide.
+
+int i, j;
+for (i = 0; i <= glob.count - 1; i++ ) {
+    for (j = 0; j <= glob.count - 1; j++ ) {
+        cairo_move_to(cr, glob.coordx[i], glob.coordy[i]);
+        cairo_line_to(cr, glob.coordx[j], glob.coordy[j]);
+    }
+}
+```
+We connect every point from the array to every other point.
+
+```cpp
+cairo_stroke(cr);
+The cairo_stroke() call draws the lines.
+
+g_signal_connect(window, "button-press-event", 
+    G_CALLBACK(clicked), NULL);
+```
+We connect the button-press-event to the clicked callback.
+
+```cpp
+if (event->button == 1) {
+    glob.coordx[glob.count] = event->x;
+    glob.coordy[glob.count++] = event->y;
+}
+```
+Inside the clicked callback, we determine if we there was a left or right click. If we click with a left mouse button, we store the x, y coordinates into the arrays.
+
+```cpp
+if (event->button == 3) {
+    gtk_widget_queue_draw(widget);
+}
+```
+By right clicking, we redraw the window.
+
+(Lines) Figure: Lines
+
+## Fill and stroke
+The stroke operation draws the outlines of shapes and the fill operation fills the insides of shapes.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+static void do_drawing(cairo_t *, GtkWidget *);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{  
+  do_drawing(cr, widget);  
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  int width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+  
+  cairo_set_line_width(cr, 9);  
+  cairo_set_source_rgb(cr, 0.69, 0.19, 0);
+  
+  cairo_translate(cr, width/2, height/2);
+  cairo_arc(cr, 0, 0, 50, 0, 2 * M_PI);
+  cairo_stroke_preserve(cr);
+
+  cairo_set_source_rgb(cr, 0.3, 0.4, 0.6); 
+  cairo_fill(cr);      
+}
+
+
+int main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+  
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); 
+  gtk_window_set_title(GTK_WINDOW(window), "Fill & stroke");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+In our example, we will draw a circle and fill it with a solid color.
+
+```cpp
+#include <math.h>
+```
+This header file is needed for the M_PI constant.
+
+```cpp
+GtkWidget *win = gtk_widget_get_toplevel(widget);
+
+int width, height;
+gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+```
+Here we get the width and height of the window. We will need these values, when we draw the circle. The circle will be resized, when we resize the window.
+
+```cpp
+cairo_set_line_width(cr, 9);  
+cairo_set_source_rgb(cr, 0.69, 0.19, 0);
+```
+We set a line width with the set_line_width() method. We set the source to some dark red colour using the set_source_rgb() method.
+
+```cpp
+cairo_translate(cr, width/2, height/2);
+cairo_arc(cr, 0, 0, 50, 0, 2 * M_PI);
+cairo_stroke_preserve(cr);
+```
+With the cairo_translate() method, we move the drawing origin to the center of the window. We want our circle to be centered. The arc() method adds a new circular path to the cairo drawing context. Finally, the stroke_preserve() method draws the outline of the circle. Unlike the stroke() method, it also preserves the shape for later drawing.
+
+```cpp
+cairo_set_source_rgb(cr, 0.3, 0.4, 0.6); 
+cairo_fill(cr);
+```
+Here we fill the cirle with blue color.
+
+(Fill and stroke) Figure: Fill and stroke
+
+## Pen dashes
+Each line can be drawn with a different pen dash. It defines the style of the line. The dash is used by the cairo_stroke() function call. The dash pattern is specified by the cairo_set_dash() function. The pattern is set by the dash array, which is an array of positive floating point values. They set the on and off parts of the dash pattern. We also specify the length of the array and the offset value. If the length is 0, the dashing is disabled. If it is 1, a symmetric pattern is asumed with alternating on and off portions of the size specified by the single value in dashes.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgba(cr, 0, 0, 0, 1);
+
+  static const double dashed1[] = {4.0, 21.0, 2.0};
+  static int len1  = sizeof(dashed1) / sizeof(dashed1[0]);
+
+  static const double dashed2[] = {14.0, 6.0};
+  static int len2  = sizeof(dashed2) / sizeof(dashed2[0]);
+
+  static const double dashed3[] = {1.0};
+
+  cairo_set_line_width(cr, 1.5);
+
+  cairo_set_dash(cr, dashed1, len1, 0);
+
+  cairo_move_to(cr, 40, 30);  
+  cairo_line_to(cr, 200, 30);
+  cairo_stroke(cr);
+
+  cairo_set_dash(cr, dashed2, len2, 1);
+
+  cairo_move_to(cr, 40, 50);  
+  cairo_line_to(cr, 200, 50);
+  cairo_stroke(cr);
+
+  cairo_set_dash(cr, dashed3, 1, 0);
+
+  cairo_move_to(cr, 40, 70);  
+  cairo_line_to(cr, 200, 70);
+  cairo_stroke(cr);  
+}
+```
+In this example, we will draw three lines with different dash patterns.
+
+```cpp
+static const double dashed1[] = {4.0, 21.0, 2.0};
+```
+We have a pattern of three numbers. We have 4 points drawn, 21 not drawn and 2 drawn. Then 4 points not drawn, 21 points drawn and 2 not drawn. This pattern takes turns until the end of the line.
+
+```cpp
+static int len1  = sizeof(dashed1) / sizeof(dashed1[0]);
+```
+We get the size of the array.
+
+```cpp
+cairo_set_dash(cr, dashed1, len1, 0);
+```
+We set the dash.
+
+```cpp
+static const double dashed3[] = {1.0};
+...
+cairo_set_dash(cr, dashed3, 1, 0);
+
+cairo_move_to(cr, 40, 70);  
+cairo_line_to(cr, 200, 70);
+cairo_stroke(cr);
+```
+These lines create a line with a pen dash of a symmetric pattern of alternating single on and off points.
+
+(Dashes) Figure: Dashes
+
+## Line caps
+The line caps are endpoints of lines.
+
+- CAIRO_LINE_CAP_SQUARE
+- CAIRO_LINE_CAP_ROUND
+- CAIRO_LINE_CAP_BUTT
+
+There are three different line cap styles in Cairo.
+
+(Line caps) Figure: Square, round and butt caps
+
+A line with a CAIRO_LINE_CAP_SQUARE cap will have a different size, than a line with a CAIRO_LINE_CAP_BUTT cap. If a line is width px wide, the line with a CAIRO_LINE_CAP_SQUARE cap will be exactly width px greater in size. width/2 px at the beginning and width/2 px at the end.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_line_width(cr, 10);
+
+  cairo_set_line_cap(cr, CAIRO_LINE_CAP_BUTT); 
+  cairo_move_to(cr, 30, 50); 
+  cairo_line_to(cr, 150, 50);
+  cairo_stroke(cr);
+
+  cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); 
+  cairo_move_to(cr, 30, 90); 
+  cairo_line_to(cr, 150, 90);
+  cairo_stroke(cr);
+
+  cairo_set_line_cap(cr, CAIRO_LINE_CAP_SQUARE); 
+  cairo_move_to(cr, 30, 130); 
+  cairo_line_to(cr, 150, 130);
+  cairo_stroke(cr);
+
+  cairo_set_line_width(cr, 1.5);
+
+  cairo_move_to(cr, 30, 40);  
+  cairo_line_to(cr, 30, 140);
+  cairo_stroke(cr);
+
+  cairo_move_to(cr, 150, 40);  
+  cairo_line_to(cr, 150, 140);
+  cairo_stroke(cr);
+
+  cairo_move_to(cr, 155, 40);  
+  cairo_line_to(cr, 155, 140);
+  cairo_stroke(cr);    
+}
+```
+The example draws three lines with three different caps. It will also graphically demonstrate the differences is size of the lines.
+
+```cpp
+cairo_set_line_width(cr, 10);
+```
+Our lines will be 10 px wide.
+
+```cpp
+cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND); 
+cairo_move_to(cr, 30, 90); 
+cairo_line_to(cr, 150, 90);
+cairo_stroke(cr);
+```
+Here we draw a horizontal line with a CAIRO_LINE_CAP_ROUND cap.
+
+```cpp
+cairo_set_line_width(cr, 1.5);
+
+cairo_move_to(cr, 30, 40);  
+cairo_line_to(cr, 30, 140);
+cairo_stroke(cr);
+```
+
+This is one of the three vertical lines used to demostrate the differences in size.
+
+(Line caps) Figure: Line caps
+
+## Line joins
+The lines can be joined using three different join styles:
+
+- CAIRO_LINE_JOIN_BEVEL
+- CAIRO_LINE_JOIN_ROUND
+- CAIRO_LINE_JOIN_MITER
+
+(Bevel, Round, Miter line joins) Figure: Bevel, Round, Miter line joins
+
+CAIRO_LINE_JOIN_BEVEL uses a cut-off join, where the join is cut off at half the line width from the joint point. CAIRO_LINE_JOIN_ROUND uses a rounded join, where the center of the circle is the joint point. CAIRO_LINE_JOIN_MITER uses a sharp, angled corner.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0.1, 0, 0);
+
+  cairo_rectangle(cr, 30, 30, 100, 100);
+  cairo_set_line_width(cr, 14);
+  cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); 
+  cairo_stroke(cr);
+
+  cairo_rectangle(cr, 160, 30, 100, 100);
+  cairo_set_line_width(cr, 14);
+  cairo_set_line_join(cr, CAIRO_LINE_JOIN_BEVEL); 
+  cairo_stroke(cr);
+
+  cairo_rectangle(cr, 100, 160, 100, 100);
+  cairo_set_line_width(cr, 14);
+  cairo_set_line_join(cr, CAIRO_LINE_JOIN_ROUND); 
+  cairo_stroke(cr);    
+}
+```
+In this example, we draw three thick rectangles with various line joins.
+
+```cpp
+cairo_rectangle(cr, 30, 30, 100, 100);
+cairo_set_line_width(cr, 14);
+cairo_set_line_join(cr, CAIRO_LINE_JOIN_MITER); 
+cairo_stroke(cr);
+```
+
+In this code example, we draw a rectangle with CAIRO_LINE_JOIN_MITER join style. The lines are 14px wide.
+
+(Line joins) Figure: Line joins
+
+In this chapter, we did some basic drawing.
\ No newline at end of file
diff --git a/src/06-shapesfills.md b/src/06-shapesfills.md
new file mode 100644
index 0000000..1cf9925
--- /dev/null
+++ b/src/06-shapesfills.md
@@ -0,0 +1,331 @@
+# Shapes and fills
+last modified July 13, 2020
+
+In this part of the Cairo tutorial, we will create some basic and more advanced shapes. We will fill them with solid colours, patterns and gradients. Gradients will be covered in a separate chapter.
+
+## Basic shapes
+The Cairo API has some basic functions to create simple shapes.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
+  cairo_set_line_width(cr, 1);
+
+  cairo_rectangle(cr, 20, 20, 120, 80);
+  cairo_rectangle(cr, 180, 20, 80, 80);
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+
+  cairo_arc(cr, 330, 60, 40, 0, 2*M_PI);
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+
+  cairo_arc(cr, 90, 160, 40, M_PI/4, M_PI);
+  cairo_close_path(cr);
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+
+  cairo_translate(cr, 220, 180);
+  cairo_scale(cr, 1, 0.7);
+  cairo_arc(cr, 0, 0, 50, 0, 2*M_PI);
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+}
+```
+In this example, we will create a rectangle, a square, a circle, an arc and an ellipse.
+
+```cpp
+cairo_rectangle(cr, 20, 20, 120, 80);
+cairo_rectangle(cr, 180, 20, 80, 80);
+```
+The cairo_rectangle() is used to create both squares and rectangles. A square is just a specific type of a rectangle.
+
+```cpp
+cairo_arc(cr, 330, 60, 40, 0, 2*M_PI);
+```
+This line creates a circle.
+
+```cpp
+cairo_scale(cr, 1, 0.7);
+cairo_arc(cr, 0, 0, 50, 0, 2*M_PI);
+```
+We use the cairo_scale() function call to create an ellipse.
+
+(Basic shapes) Figure: Basic shapes
+
+Other shapes can be created using a combination of basic primitives.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+int points[11][2] = { 
+    { 0, 85 }, 
+    { 75, 75 }, 
+    { 100, 10 }, 
+    { 125, 75 }, 
+    { 200, 85 },
+    { 150, 125 }, 
+    { 160, 190 },
+    { 100, 150 }, 
+    { 40, 190 },
+    { 50, 125 },
+    { 0, 85 } 
+};
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{
+  do_drawing(cr);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{ 
+  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
+  cairo_set_line_width(cr, 1);
+
+  gint i;
+  for (i = 0; i < 10; i++) {
+      cairo_line_to(cr, points[i][0], points[i][1]);
+  }
+
+  cairo_close_path(cr);
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+
+  cairo_move_to(cr, 240, 40);
+  cairo_line_to(cr, 240, 160);
+  cairo_line_to(cr, 350, 160);
+  cairo_close_path(cr);
+
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);
+
+  cairo_move_to(cr, 380, 40);
+  cairo_line_to(cr, 380, 160);
+  cairo_line_to(cr, 450, 160);
+  cairo_curve_to(cr, 440, 155, 380, 145, 380, 40);
+
+  cairo_stroke_preserve(cr);
+  cairo_fill(cr);  
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 460, 240); 
+  gtk_window_set_title(GTK_WINDOW(window), "Other shapes");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+
+In this example, we create a star object a triangle and a modified triangle. These objects are created using lines and one curve.
+
+```cpp
+gint i;
+for (i = 0; i < 10; i++ ) {
+    cairo_line_to(cr, points[i][0], points[i][1]);
+}
+
+cairo_close_path(cr);
+```
+
+The star is drawn by joining all the points that are in the points array. The star is finished by calling the cairo_close_path() function, which joins the last two points of a star.
+
+```cpp
+cairo_move_to(cr, 380, 40);
+cairo_line_to(cr, 380, 160);
+cairo_line_to(cr, 450, 160);
+cairo_curve_to(cr, 440, 155, 380, 145, 380, 40);
+```
+The modified triangle is a simple combination of two lines and one curve.
+
+(Other shapes) Figure: Other shapes
+
+## Fills
+Fills fill the interiors of shapes. Fills can be solid colours, patters or gradients.
+
+### Solid colours
+A colour is an object representing a combination of Red, Green, and Blue (RGB) intensity values. Cairo valid RGB values are in the range 0 to 1.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{ 
+  cairo_set_source_rgb(cr, 0.5, 0.5, 1);
+  cairo_rectangle(cr, 20, 20, 100, 100);
+  cairo_fill(cr);
+
+  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
+  cairo_rectangle(cr, 150, 20, 100, 100);
+  cairo_fill(cr);
+ 
+  cairo_set_source_rgb(cr, 0, 0.3, 0);
+  cairo_rectangle(cr, 20, 140, 100, 100);
+  cairo_fill(cr);
+
+  cairo_set_source_rgb(cr, 1, 0, 0.5);
+  cairo_rectangle(cr, 150, 140, 100, 100);
+  cairo_fill(cr);  
+}
+```
+In the example we draw four coloured rectangles.
+
+```cpp
+cairo_set_source_rgb(cr, 0.5, 0.5, 1);
+cairo_rectangle(cr, 20, 20, 100, 100);
+cairo_fill(cr);
+```
+The cairo_set_source_rgb() function call sets the source to an opaque colour. The parameters are the Red, Green, and Blue intensity values. The source is used to fill the interior of a rectangle by calling the cairo_fill() function.
+
+(Solid colours) Figure: Solid colours
+
+### Patterns
+Patterns are complex graphical objects that can fill the shapes.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+cairo_surface_t *surface1;
+cairo_surface_t *surface2;
+cairo_surface_t *surface3;
+cairo_surface_t *surface4;
+
+static void create_surfaces() {
+  surface1 = cairo_image_surface_create_from_png("blueweb.png");
+  surface2 = cairo_image_surface_create_from_png("maple.png");
+  surface3 = cairo_image_surface_create_from_png("crack.png");
+  surface4 = cairo_image_surface_create_from_png("chocolate.png");
+}
+
+static void destroy_surfaces() {
+  cairo_surface_destroy(surface1);
+  cairo_surface_destroy(surface2);
+  cairo_surface_destroy(surface3);
+  cairo_surface_destroy(surface4);
+}
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{
+  do_drawing(cr);
+  
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_pattern_t *pattern1;
+  cairo_pattern_t *pattern2;
+  cairo_pattern_t *pattern3;
+  cairo_pattern_t *pattern4;
+
+  pattern1 = cairo_pattern_create_for_surface(surface1);
+  pattern2 = cairo_pattern_create_for_surface(surface2);
+  pattern3 = cairo_pattern_create_for_surface(surface3);
+  pattern4 = cairo_pattern_create_for_surface(surface4);
+
+  cairo_set_source(cr, pattern1);
+  cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+  cairo_rectangle(cr, 20, 20, 100, 100);
+  cairo_fill(cr);
+
+  cairo_set_source(cr, pattern2); 
+  cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT); 
+  cairo_rectangle(cr, 150, 20, 100, 100);
+  cairo_fill(cr);
+
+  cairo_set_source(cr, pattern3);
+  cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+  cairo_rectangle(cr, 20, 140, 100, 100);
+  cairo_fill(cr);
+
+  cairo_set_source(cr, pattern4);
+  cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+  cairo_rectangle(cr, 150, 140, 100, 100);
+  cairo_fill(cr);
+
+  cairo_pattern_destroy(pattern1);
+  cairo_pattern_destroy(pattern2);
+  cairo_pattern_destroy(pattern3);
+  cairo_pattern_destroy(pattern4);      
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);  
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  create_surfaces();
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 270, 260); 
+  gtk_window_set_title(GTK_WINDOW(window), "Patterns");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  destroy_surfaces();
+
+  return 0;
+}
+```
+
+In this example we draw four rectangles again. This time, we fill them with some patterns. We use four pattern images from the Gimp image manipulation program. We must retain the original size of those patterns, because we are going to tile them.
+
+We create image surfaces outside the on_draw_event() function. It would not be efficient to read from harddisk each time, the window needs to be redrawn.
+
+```cpp
+pattern1 = cairo_pattern_create_for_surface(surface1);
+```
+We create a pattern from the surface by calling the cairo_pattern_create_for_surface() function.
+
+```cpp
+cairo_set_source(cr, pattern1);
+cairo_pattern_set_extend(cairo_get_source(cr), CAIRO_EXTEND_REPEAT);
+cairo_rectangle(cr, 20, 20, 100, 100);
+cairo_fill(cr);
+```
+Here we draw our first rectangle. The cairo_set_source() tells the Cairo context to use a pattern as a source for drawing. The image patterns may not fit exactly the shape. We set the mode to CAIRO_EXTEND_REPEAT, which causes the pattern to be tiled by repeating. The cairo_rectangle() creates a rectangular path. Finally, cairo_fill() fills the path with the source.
+
+This chapter covered Cairo shapes and fills.
\ No newline at end of file
diff --git a/src/07-gradients.md b/src/07-gradients.md
new file mode 100644
index 0000000..01add4e
--- /dev/null
+++ b/src/07-gradients.md
@@ -0,0 +1,244 @@
+# Gradients
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will cover gradients. We will mention linear and radial gradients.
+
+In computer graphics, gradient is a smooth blending of shades from light to dark or from one colour to another. In 2D drawing programs and paint programs, gradients are used to create colourful backgrounds and special effects as well as to simulate lights and shadows. (answers.com)
+
+## Linear gradients
+Linear gradients are blendings of colours or shades of colours along a line. They are created with the cairo_pattern_create_linear() function.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+void draw_gradient1(cairo_t *);
+void draw_gradient2(cairo_t *);
+void draw_gradient3(cairo_t *);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{         
+  draw_gradient1(cr);
+  draw_gradient2(cr);
+  draw_gradient3(cr);  
+
+  return FALSE;
+}
+
+void draw_gradient1(cairo_t *cr)
+{
+  cairo_pattern_t *pat1;  
+  pat1 = cairo_pattern_create_linear(0.0, 0.0,  350.0, 350.0);
+
+  gdouble j;
+  gint count = 1;
+  for ( j = 0.1; j < 1; j += 0.1 ) {
+      if (( count % 2 ))  {
+          cairo_pattern_add_color_stop_rgb(pat1, j, 0, 0, 0);
+      } else { 
+          cairo_pattern_add_color_stop_rgb(pat1, j, 1, 0, 0);
+      }
+   count++;
+  }
+
+  cairo_rectangle(cr, 20, 20, 300, 100);
+  cairo_set_source(cr, pat1);
+  cairo_fill(cr);  
+  
+  cairo_pattern_destroy(pat1);
+}
+
+void draw_gradient2(cairo_t *cr)
+{
+  cairo_pattern_t *pat2;
+  pat2 = cairo_pattern_create_linear(0.0, 0.0,  350.0, 0.0);
+
+  gdouble i;
+  gint count = 1;
+  for ( i = 0.05; i < 0.95; i += 0.025 ) {
+      if (( count % 2 ))  {
+          cairo_pattern_add_color_stop_rgb(pat2, i, 0, 0, 0);
+      } else { 
+          cairo_pattern_add_color_stop_rgb(pat2, i, 0, 0, 1);
+      }
+   count++;
+  }
+
+  cairo_rectangle(cr, 20, 140, 300, 100);
+  cairo_set_source(cr, pat2);
+  cairo_fill(cr);  
+  
+  cairo_pattern_destroy(pat2);
+}
+
+void draw_gradient3(cairo_t *cr)
+{
+  cairo_pattern_t *pat3;
+  pat3 = cairo_pattern_create_linear(20.0, 260.0, 20.0, 360.0);
+
+  cairo_pattern_add_color_stop_rgb(pat3, 0.1, 0, 0, 0);
+  cairo_pattern_add_color_stop_rgb(pat3, 0.5, 1, 1, 0);
+  cairo_pattern_add_color_stop_rgb(pat3, 0.9, 0, 0, 0);
+
+  cairo_rectangle(cr, 20, 260, 300, 100);
+  cairo_set_source(cr, pat3);
+  cairo_fill(cr);  
+  
+  cairo_pattern_destroy(pat3);
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 340, 390); 
+  gtk_window_set_title(GTK_WINDOW(window), "Linear gradients");
+
+  gtk_widget_set_app_paintable(window, TRUE);
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+
+The example draws three rectangles filled with linear gradients.
+
+```cpp
+pat3 = cairo_pattern_create_linear(20.0, 260.0, 20.0, 360.0);
+```
+Here we create a linear gradient pattern. The parameters specify the line, along which we draw the gradient. In our case it is a vertical line.
+
+```cpp
+cairo_pattern_add_color_stop_rgb(pat3, 0.1, 0, 0, 0);
+cairo_pattern_add_color_stop_rgb(pat3, 0.5, 1, 1, 0);
+cairo_pattern_add_color_stop_rgb(pat3, 0.9, 0, 0, 0);
+```
+We define colour stops to produce our gradient pattern. In this case, the gradient is a blending of black and yellow colours. By adding two black and one yellow stops, we create a horizontal gradient pattern. What these stops actually mean? In our case, we begin with black colour, which will stop at 1/10 of the size. Then we begin to gradually paint in yellow, which will culminate at the centre of the shape. The yellow colour stops at 9/10 of the size, where we begin painting in black again, until the end.
+
+(Linear gradients) Figure: Linear gradients
+
+## Radial gradients
+Radial gradients are blendings of colours or shades of colours between two circles. The cairo_pattern_create_radial() function s is used to create radial gradients in Cairo.
+
+```cpp
+#include <cairo.h>
+#include <math.h>
+#include <gtk/gtk.h>
+
+void draw_gradient1(cairo_t *);
+void draw_gradient2(cairo_t *);
+
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{         
+  draw_gradient1(cr);
+  draw_gradient2(cr); 
+
+  return FALSE;
+}
+
+void draw_gradient1(cairo_t *cr)
+{
+  cairo_pattern_t *r1; 
+    
+  cairo_set_source_rgba(cr, 0, 0, 0, 1);
+  cairo_set_line_width(cr, 12);  
+  cairo_translate(cr, 60, 60);
+  
+  r1 = cairo_pattern_create_radial(30, 30, 10, 30, 30, 90);
+  cairo_pattern_add_color_stop_rgba(r1, 0, 1, 1, 1, 1);
+  cairo_pattern_add_color_stop_rgba(r1, 1, 0.6, 0.6, 0.6, 1);
+  cairo_set_source(cr, r1);
+  cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
+  cairo_fill(cr);
+         
+  cairo_pattern_destroy(r1);
+}
+
+void draw_gradient2(cairo_t *cr)
+{
+  cairo_pattern_t *r2; 
+  
+  cairo_translate(cr, 120, 0);
+  
+  r2 = cairo_pattern_create_radial(0, 0, 10, 0, 0, 40);  
+  cairo_pattern_add_color_stop_rgb(r2, 0, 1, 1, 0);
+  cairo_pattern_add_color_stop_rgb(r2, 0.8, 0, 0, 0);
+  cairo_set_source(cr, r2);
+  cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
+  cairo_fill(cr);     
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 300, 200); 
+  gtk_window_set_title(GTK_WINDOW(window), "Radial gradients");
+
+  gtk_widget_set_app_paintable(window, TRUE);
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+In the example, we draw two radial gradients.
+
+```cpp
+r1 = cairo_pattern_create_radial(30, 30, 10, 30, 30, 90);
+cairo_pattern_add_color_stop_rgba(r1, 0, 1, 1, 1, 1);
+cairo_pattern_add_color_stop_rgba(r1, 1, 0.6, 0.6, 0.6, 1);
+cairo_set_source(cr, r1);
+cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
+cairo_fill(cr);
+```
+We draw a circle and fill its inside with a radial gradient. The radial gradient is defined by two circles. The cairo_pattern_add_color_stop_rgba() function defines the colours. We can experiment with the position of the circles or the length of their radius. In the first gradient example, we have created an object which resembles a 3D shape.
+
+```cpp
+r2 = cairo_pattern_create_radial(0, 0, 10, 0, 0, 40);  
+cairo_pattern_add_color_stop_rgb(r2, 0, 1, 1, 0);
+cairo_pattern_add_color_stop_rgb(r2, 0.8, 0, 0, 0);
+cairo_set_source(cr, r2);
+cairo_arc(cr, 0, 0, 40, 0, M_PI * 2);
+cairo_fill(cr);
+```
+In this example, the circles that define the radial gradient and the custom drawn circle have a common center point.
+
+(Radial gradients) Figure: Radial gradients
+
+In this chapter of the Cairo graphics tutorial we have covered gradients.
\ No newline at end of file
diff --git a/src/08-transparency.md b/src/08-transparency.md
new file mode 100644
index 0000000..d95b0e5
--- /dev/null
+++ b/src/08-transparency.md
@@ -0,0 +1,361 @@
+# Transparency
+last modified July 13, 2020
+
+In this part of the Cairo C API tutorial, we will talk about transparency. We will provide some basic definitions and two interesting transparency effects.
+
+Transparency is the quality of being able to see through a material. The easiest way to understand transparency is to imagine a piece of glass or water. Technically, the rays of light can go through the glass and this way we can see objects behind the glass.
+
+In computer graphics, we can achieve transparency effects using alpha compositing. Alpha compositing is the process of combining an image with a background to create the appearance of partial transparency. The composition process uses an alpha channel. Alpha channel is an 8-bit layer in a graphics file format that is used for expressing translucency (transparency). The extra eight bits per pixel serves as a mask and represents 256 levels of translucency.
+
+## Transparent rectangles
+The first example will draw ten rectangles with different levels of transparency.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  gint i;
+  for ( i = 1; i <= 10; i++) {
+      cairo_set_source_rgba(cr, 0, 0, 1, i*0.1);
+      cairo_rectangle(cr, 50*i, 20, 40, 40);
+      cairo_fill(cr);  
+  }      
+}
+```
+The cairo_set_source_rgba() has an optional alpha parameter to provide transparency. This code creates ten rectangles with alpha values from 0.1 ... 1.
+
+(Transparency) Figure: Transparency
+
+## Puff effect
+In the following example, we create a puff effect. The example will display a growing centered text that will gradually fade out from some point. This is a very common effect which we can often see in flash animations. The cairo_paint_with_alpha() method is crucial to create the effect.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+void do_drawing(cairo_t *, GtkWidget *);
+
+struct {
+  gboolean timer; 
+  gdouble alpha;
+  gdouble size;
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr, widget);
+
+  return FALSE;
+}
+
+void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  cairo_text_extents_t extents;
+
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);  
+  
+  gint x = width/2;
+  gint y = height/2;
+  
+  cairo_set_source_rgb(cr, 0.5, 0, 0); 
+  cairo_paint(cr);   
+
+  cairo_select_font_face(cr, "Courier",
+      CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_BOLD);
+ 
+  glob.size += 0.8;
+
+  if (glob.size > 20) {
+      glob.alpha -= 0.01;
+  }
+
+  cairo_set_font_size(cr, glob.size);
+  cairo_set_source_rgb(cr, 1, 1, 1); 
+
+  cairo_text_extents(cr, "ZetCode", &extents);
+  cairo_move_to(cr, x - extents.width/2, y);
+  cairo_text_path(cr, "ZetCode");
+  cairo_clip(cr);
+
+  cairo_paint_with_alpha(cr, glob.alpha);
+  
+  if (glob.alpha <= 0) {
+      glob.timer = FALSE;
+  }     
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{ 
+  if (!glob.timer) return FALSE;
+  gtk_widget_queue_draw(widget);
+
+  return TRUE;
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+  
+  glob.timer = TRUE;
+  glob.alpha = 1.0;
+  glob.size = 1.0;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+ 
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 350, 200); 
+  gtk_window_set_title(GTK_WINDOW(window), "Puff");
+
+  g_timeout_add(14, (GSourceFunc) time_handler, (gpointer) window);
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+
+The example creates a growing and fading text on the window.
+
+```cpp
+struct {
+  gboolean timer; 
+  gdouble alpha;
+  gdouble size;
+} glob; 
+```
+Here we define some variables inside a structure. This is used to avoid using globals.
+
+```cpp
+draw_text(cr, widget); 
+```
+
+The actual drawing of the text is delegated to the draw_text() function.
+
+```cpp
+GtkWidget *win = gtk_widget_get_toplevel(widget);
+
+gint width, height;
+gtk_window_get_size(GTK_WINDOW(win), &width, &height);  
+
+gint x = width/2;
+gint y = height/2;
+```
+The text is going to be centered on the window. Therefore we need to find out the size of the parent widget.
+
+```cpp
+cairo_set_source_rgb(cr, 0.5, 0, 0); 
+cairo_paint(cr); 
+```
+The background of the window is filled with some dark red colour.
+
+```cpp
+cairo_select_font_face(cr, "Courier",
+    CAIRO_FONT_SLANT_NORMAL,
+    CAIRO_FONT_WEIGHT_BOLD);
+```
+The text is going to be in Courier bold font.
+
+```cpp
+glob.size += 0.8;
+
+if (glob.size > 20) {
+    glob.alpha -= 0.01;
+}
+```
+The size of the text is increased by 0.8 units. After it has reached 20 units, the alpha value starts decreasing. And the text fades away slowly.
+
+```cpp
+cairo_text_extents(cr, "ZetCode", &extents);
+cairo_move_to(cr, x - extents.width/2, y);
+```
+We get the text metrics. We will use only the text width. We move to a position where the text will be centered on the window.
+
+```cpp
+cairo_text_path(cr, "ZetCode");
+cairo_clip(cr);
+
+cairo_paint_with_alpha(cr, glob.alpha);
+```
+We get the path of the text with the cairo_text_path() method. We restrict the painting to the current path using the cairo_clip() method. The cairo_paint_with_alpha() method paints the current source everywhere within the current clip region using a mask of the alpha value.
+
+```cpp
+glob.timer = TRUE;
+glob.alpha = 1.0;
+glob.size = 1.0;
+```
+We initiate three variables.
+
+```cpp
+static gboolean time_handler(GtkWidget *widget)
+{
+  if (!glob.timer) return FALSE;
+
+  gtk_widget_queue_draw(widget);
+
+  return TRUE;
+}
+```
+The main function of the time_handler call is to redraw the window regularly. When the function returns FALSE, the timeout function will cease to work.
+
+```cpp
+g_timeout_add(14, (GSourceFunc) time_handler, (gpointer) window);
+```
+We create a timer function. This function will call time_handler every 14 ms.
+
+(Puff effect) Figure: Puff effect
+
+## Waiting demo
+In this examle, we use transparency effect to create a waiting demo. We will draw 8 lines that will gradually fade out creating an illusion, that a line is moving. Such effects are often used to inform users that a lengthy task is going on behind the scenes. An example is streaming video over the Internet.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+static void do_drawing(cairo_t *, GtkWidget *);
+
+struct {
+  gushort count;
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr, widget);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{  
+  static gdouble const trs[8][8] = {
+      { 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
+      { 1.0, 0.0,  0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
+      { 0.9, 1.0,  0.0,  0.15, 0.3, 0.5, 0.65, 0.8 },
+      { 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5, 0.65},
+      { 0.65, 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5 },
+      { 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15, 0.3 },
+      { 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15 },
+      { 0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0, }
+  };
+
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+
+  cairo_translate(cr, width/2, height/2);
+
+  gint i = 0;
+  for (i = 0; i < 8; i++) {
+      cairo_set_line_width(cr, 3);
+      cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
+      cairo_set_source_rgba(cr, 0, 0, 0, trs[glob.count%8][i]);
+
+      cairo_move_to(cr, 0.0, -10.0);
+      cairo_line_to(cr, 0.0, -40.0);
+      cairo_rotate(cr, M_PI/4);
+
+      cairo_stroke(cr);
+  }   
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{
+  glob.count += 1;
+  gtk_widget_queue_draw(widget);
+  
+  return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+  
+  glob.count = 0;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 250, 150); 
+  gtk_window_set_title(GTK_WINDOW(window), "Waiting demo");
+
+  g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
+  gtk_widget_show_all(window);  
+
+  gtk_main();
+
+  return 0;
+}
+```
+We draw eight lines with eight different alpha values.
+
+```cpp
+static gdouble const trs[8][8] = {
+     { 0.0, 0.15, 0.30, 0.5, 0.65, 0.80, 0.9, 1.0 },
+     { 1.0, 0.0,  0.15, 0.30, 0.5, 0.65, 0.8, 0.9 },
+     { 0.9, 1.0,  0.0,  0.15, 0.3, 0.5, 0.65, 0.8 },
+     { 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5, 0.65},
+     { 0.65, 0.8, 0.9,  1.0,  0.0,  0.15, 0.3, 0.5 },
+     { 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15, 0.3 },
+     { 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0,  0.15 },
+     { 0.15, 0.3, 0.5, 0.65, 0.8, 0.9, 1.0,  0.0, }
+};
+```
+This is a two dimensional array of transparency values used in this demo. There are 8 rows, each for one state. Each of the 8 lines will continuosly use these values.
+
+```cpp
+cairo_set_line_width(cr, 3);
+cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
+```
+We make the lines a bit thicker, so that they are better visible. We draw the lines with rouded caps.
+
+```cpp
+cairo_set_source_rgba(cr, 0, 0, 0, trs[glob.count%8][i]);
+```
+Here we define the transparency value for a line.
+
+```cpp
+cairo_move_to(cr, 0.0, -10.0);
+cairo_line_to(cr, 0.0, -40.0);
+cairo_rotate(cr, M_PI/4);
+```
+These code will draw each of the eight lines.
+
+```cpp
+g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
+```
+We use a timer function to create animation.
+
+(Waiting demo) Figure: Waiting demo
+
+In this part of the Cairo tutorial, we have covered transparency.
\ No newline at end of file
diff --git a/src/09-compositing.md b/src/09-compositing.md
new file mode 100644
index 0000000..bf1194f
--- /dev/null
+++ b/src/09-compositing.md
@@ -0,0 +1,153 @@
+# Compositing
+last modified July 13, 2020
+
+In this part of the Cairo graphics programming tutorial, we will define compositing operations.
+
+Compositing is the combining of visual elements from separate sources into single images. They are used to create the illusion that all those elements are parts of the same scene. Compositing is widely used in film industry to create crowds, entire new worlds which would be expensive or impossible to create otherwise. (wikipedia.org)
+
+## Operations
+There are several compositing operations. The Cairo graphics library has 14 different compositing operations.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+void do_drawing(cairo_t *cr, gint x, gint w,
+    gint h, cairo_operator_t op)
+{
+  cairo_t *first_cr, *second_cr;
+  cairo_surface_t *first, *second;
+
+  first = cairo_surface_create_similar(cairo_get_target(cr),
+      CAIRO_CONTENT_COLOR_ALPHA, w, h);
+
+  second = cairo_surface_create_similar(cairo_get_target(cr),
+      CAIRO_CONTENT_COLOR_ALPHA, w, h);
+
+  first_cr = cairo_create(first);
+  cairo_set_source_rgb(first_cr, 0, 0, 0.4);
+  cairo_rectangle(first_cr, x, 20, 50, 50);
+  cairo_fill(first_cr);
+
+  second_cr = cairo_create(second);
+  cairo_set_source_rgb(second_cr, 0.5, 0.5, 0);
+  cairo_rectangle(second_cr, x+10, 40, 50, 50);
+  cairo_fill(second_cr);
+
+  cairo_set_operator(first_cr, op);
+  cairo_set_source_surface(first_cr, second, 0, 0);
+  cairo_paint(first_cr);
+
+  cairo_set_source_surface(cr, first, 0, 0);
+  cairo_paint(cr);
+
+  cairo_surface_destroy(first);
+  cairo_surface_destroy(second);
+
+  cairo_destroy(first_cr);
+  cairo_destroy(second_cr);
+
+}
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  cairo_operator_t oper[] = {
+    CAIRO_OPERATOR_DEST_OVER, 
+    CAIRO_OPERATOR_DEST_IN, 
+    CAIRO_OPERATOR_OUT,
+    CAIRO_OPERATOR_ADD, 
+    CAIRO_OPERATOR_ATOP,
+    CAIRO_OPERATOR_DEST_ATOP,
+  };
+  
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+
+  gint i;
+  gint x, y;
+  for(x=20, y=20, i=0; i < 6; x+=80, i++) {
+      do_drawing(cr, x, width, height, oper[i] );
+  }
+
+  return FALSE;
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 510, 120);
+  gtk_window_set_title(GTK_WINDOW(window), "Compositing operations");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+In our example, we will show 6 different compositing operations on two squares.
+
+```cpp
+first = cairo_surface_create_similar(cairo_get_target(cr),
+    CAIRO_CONTENT_COLOR_ALPHA, w, h);
+
+second = cairo_surface_create_similar(cairo_get_target(cr),
+    CAIRO_CONTENT_COLOR_ALPHA, w, h);
+``
+We create two surfaces.
+
+```cpp
+first_cr = cairo_create(first);
+cairo_set_source_rgb(first_cr, 0, 0, 0.4);
+cairo_rectangle(first_cr, x, 20, 50, 50);
+cairo_fill(first_cr);
+```
+We draw a rectangle into the surface.
+
+```cpp
+cairo_set_operator(first_cr, op);
+cairo_set_source_surface(first_cr, second, 0, 0);
+cairo_paint(first_cr);
+```
+We apply the compositing operation on the surfaces.
+
+```cpp
+cairo_set_source_surface(cr, first, 0, 0);
+cairo_paint(cr);
+```
+Finally we draw the outcome onto the GTK+ window.
+
+```cpp
+cairo_operator_t oper[] = {
+  CAIRO_OPERATOR_DEST_OVER, 
+  CAIRO_OPERATOR_DEST_IN, 
+  CAIRO_OPERATOR_OUT,
+  CAIRO_OPERATOR_ADD, 
+  CAIRO_OPERATOR_ATOP,
+  CAIRO_OPERATOR_DEST_ATOP,
+};
+```
+In our example, we use these six compositing operations.
+
+(Compositing operations) Figure: Compositing operations
+
+This chapter covered Cairo compositing.
\ No newline at end of file
diff --git a/src/10-clippingmasking.md b/src/10-clippingmasking.md
new file mode 100644
index 0000000..e6950d0
--- /dev/null
+++ b/src/10-clippingmasking.md
@@ -0,0 +1,390 @@
+# Clipping and masking
+last modified July 13, 2020
+
+In this part of the Cairo tutorial, we will talk about clipping and masking.
+
+## Clipping
+Clipping is restricting of drawing to a certain area. This is done for efficiency reasons and to create interesting effects.
+
+In the following example we will be clipping an image.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+static void do_drawing(cairo_t *, GtkWidget *);
+
+struct {
+  cairo_surface_t *image;
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr, widget);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  static gint pos_x = 128;
+  static gint pos_y = 128;
+  static gint radius = 40;  
+  static gint delta[] = { 3, 3 };
+
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+
+  if (pos_x < 0 + radius) {
+      delta[0] = rand() % 4 + 5;
+  } else if (pos_x > width - radius) {
+      delta[0] = -(rand() % 4 + 5);
+  }
+
+  if (pos_y < 0 + radius) {
+      delta[1] = rand() % 4 + 5;
+  } else if (pos_y > height - radius) {
+      delta[1] = -(rand() % 4 + 5);
+  }
+
+  pos_x += delta[0];
+  pos_y += delta[1];
+
+  cairo_set_source_surface(cr, glob.image, 1, 1);
+  cairo_arc(cr, pos_x, pos_y, radius, 0, 2*M_PI);
+  cairo_clip(cr);
+  cairo_paint(cr);      
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{  
+  gtk_widget_queue_draw(widget);
+  return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+  gint width, height;  
+
+  glob.image = cairo_image_surface_create_from_png("turnacastle.png");
+  width = cairo_image_surface_get_width(glob.image);
+  height = cairo_image_surface_get_height(glob.image); 
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), width+2, height+2); 
+  gtk_window_set_title(GTK_WINDOW(window), "Clip image");
+
+  gtk_widget_show_all(window);
+  g_timeout_add(100, (GSourceFunc) time_handler, (gpointer) window);
+
+  gtk_main();
+
+  cairo_surface_destroy(glob.image);
+
+  return 0;
+}
+```
+In this example, we will clip an image. A circle is moving on the screen and showing a part of the underlying image. This is as if we looked through a hole.
+
+```cpp
+if (pos_x < 0 + radius) {
+    delta[0] = rand() % 4 + 5;
+} else if (pos_x > width - radius) {
+    delta[0] = -(rand() % 4 + 5);
+}
+```
+If the circle hits the left or the right side of the window, the direction of the circle movement changes randomly. Same applies for the top and bottom sides.
+
+```cpp
+cairo_set_source_surface(cr, glob.image, 1, 1);
+cairo_arc(cr, pos_x, pos_y, radius, 0, 2*M_PI);
+```
+Here we draw the image and a circle. Notice that we do not draw onto the window at the moment, but only in memory.
+
+```cpp
+cairo_clip(cr);
+```
+The cairo_clip() sets a clipping region. The clipping region is the current path used. The current path was created by the cairo_arc() function call.
+
+```cpp
+cairo_paint(cr);
+```
+The cairo_paint() paints the current source everywhere within the current clip region.
+
+```cpp
+glob.image = cairo_image_surface_create_from_png("turnacastle.png");
+```
+An image surface is created from a PNG image using the cairo_image_surface_create_from_png() function.
+
+(Clipping image) Figure: Clipping image
+
+## Mask
+Before the source is applied to the surface, it is filtered first. The mask is used as a filter. The mask determines where the source is applied and where not. Opaque parts of the mask allow to copy the source. Transparent parts do not let to copy the source to the surface.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+
+static void do_drawing(cairo_t *);
+
+struct {
+  cairo_surface_t *surface;
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);  
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0, 0, 0);  
+  cairo_mask_surface(cr, glob.surface, 0, 0);
+  cairo_fill(cr);      
+}
+
+static void create_surface()
+{
+  glob.surface = cairo_image_surface_create_from_png("omen.png");
+}
+
+static void destroy_surface()
+{
+  cairo_surface_destroy(glob.surface);
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;  
+
+  gtk_init(&argc, &argv);
+  
+  create_surface();
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);  
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 305, 100); 
+  gtk_window_set_title(GTK_WINDOW(window), "Mask");
+  
+  gtk_widget_show_all(window);
+
+  gtk_main();
+  
+  destroy_surface();
+
+  return 0;
+}
+```
+This small example clearly shows the basic idea behind the mask. The mask determines where to paint and where not to paint.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0, 0, 0);  
+  cairo_mask_surface(cr, glob.surface, 0, 0);
+  cairo_fill(cr);      
+}
+```
+In the do_drawing() function, we use an image as a mask. And it is therefore displayed on the window.
+
+(Applying a mask) Figure: Applying a mask
+
+## Blind down effect
+In this code example, we will blind down our image. This is similar to what we do with a roller-blind.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+
+static void do_drawing(cairo_t *);
+
+struct {
+  cairo_surface_t *image;
+  cairo_surface_t *surface;
+  gboolean timer;
+  gint img_width;
+  gint img_height;
+} glob;
+
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);
+  
+  return FALSE;
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{
+  if (!glob.timer) return FALSE;
+  
+  gtk_widget_queue_draw(widget);
+  return TRUE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_t *ic;    
+  static gint h = 0;     
+  
+  ic = cairo_create(glob.surface);
+
+  cairo_rectangle(ic, 0, 0, glob.img_width, h);
+  cairo_fill(ic);
+
+  h += 1;
+  if ( h == glob.img_height) glob.timer = FALSE;
+  
+  cairo_set_source_surface(cr, glob.image, 10, 10);
+  cairo_mask_surface(cr, glob.surface, 10, 10);
+  
+  cairo_destroy(ic);  
+}
+
+static void init_vars()
+{  
+  glob.timer = TRUE;
+  glob.image = cairo_image_surface_create_from_png("beckov.png");  
+  glob.img_width = cairo_image_surface_get_width(glob.image);
+  glob.img_height = cairo_image_surface_get_height(glob.image);  
+  glob.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
+                     glob.img_width, glob.img_height);
+}
+
+static void cleanup()
+{
+  cairo_surface_destroy(glob.image);
+  cairo_surface_destroy(glob.surface);   
+}
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;    
+
+  gtk_init(&argc, &argv);
+  
+  init_vars();
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER(window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+ 
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 325, 250); 
+  gtk_window_set_title(GTK_WINDOW(window), "Blind down");
+
+  g_timeout_add(15, (GSourceFunc) time_handler, (gpointer) window);
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+  
+  cleanup();
+
+  return 0;
+}
+```
+The idea behind the blind down effect is simple. The image is h pixels high. We draw 0, 1, 2 ... lines of 1px height. Each cycle the portion of the image is 1px higher, until the whole image is visible.
+
+```cpp
+struct {
+  cairo_surface_t *image;
+  cairo_surface_t *surface;
+  gboolean timer;
+  gint img_width;
+  gint img_height;
+} glob;
+```
+In the glob structure, we will store two surfaces, a timer and the image width and height variables.
+
+```cpp
+static void init_vars()
+{  
+  glob.timer = TRUE;
+  glob.image = cairo_image_surface_create_from_png("beckov.png");  
+  glob.img_width = cairo_image_surface_get_width(glob.image);
+  glob.img_height = cairo_image_surface_get_height(glob.image);  
+  glob.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
+                     glob.img_width, glob.img_height);
+}
+```
+In the init_vars() function, we initiate the previously declared variables. The last line creates an empty image surface. It is going to be filled with lines of pixels from the image surface that we have created earlier.
+
+```cpp
+ic = cairo_create(glob.surface);
+```
+We create a cairo context from the empty image source.
+
+```cpp
+cairo_rectangle(ic, 0, 0, glob.img_width, h);
+cairo_fill(ic);
+```
+We draw a rectangle into the initially empty image. The rectangle will be 1px higher each cycle. The image created this way will serve as a mask later.
+
+```cpp
+h += 1;
+```
+The height of the image to show is increased by one unit.
+
+```cpp
+if ( h == glob.img_height) glob.timer = FALSE;
+```
+We stop the timer function when we draw the whole image on the GTK window.
+
+```cpp
+cairo_set_source_surface(cr, glob.image, 10, 10);
+cairo_mask_surface(cr, glob.surface, 10, 10);
+```
+The image of a castle is set as a source for painting. The cairo_mask_surface() paints the current source using the alpha channel of surface as a mask.
+
+```cpp
+static void cleanup()
+{
+  cairo_surface_destroy(glob.image);
+  cairo_surface_destroy(glob.surface);   
+}
+```
+In the cleanup() function we destroy the created surfaces.
+
+This chapter was about clipping and masking in Cairo.
\ No newline at end of file
diff --git a/src/11-transformations.md b/src/11-transformations.md
new file mode 100644
index 0000000..735b070
--- /dev/null
+++ b/src/11-transformations.md
@@ -0,0 +1,416 @@
+# Transformations
+last modified July 13, 2020
+
+In this part of the Cairo graphics programming tutorial, we will talk about transformations.
+
+An affine transform is composed of zero or more linear transformations (rotation, scaling or shear) and translation (shift). Several linear transformations can be combined into a single matrix. A rotation is a transformation that moves a rigid body around a fixed point. A scaling is a transformation that enlarges or diminishes objects. The scale factor is the same in all directions.
+
+A translation is a transformation that moves every point a constant distance in a specified direction. A shear is a transformation that moves an object perpendicular to a given axis, with greater value on one side of the axis than the other.
+
+## Translation
+The following example describes a simple translation.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{ 
+  cairo_set_source_rgb(cr, 0.2, 0.3, 0.8);
+  cairo_rectangle(cr, 10, 10, 30, 30);
+  cairo_fill(cr);
+
+  cairo_translate(cr, 20, 20);
+  cairo_set_source_rgb(cr, 0.8, 0.3, 0.2);
+  cairo_rectangle(cr, 0, 0, 30, 30);
+  cairo_fill(cr);
+  
+  cairo_translate(cr, 30, 30);
+  cairo_set_source_rgb(cr, 0.8, 0.8, 0.2);
+  cairo_rectangle(cr, 0, 0, 30, 30);
+  cairo_fill(cr);
+  
+  cairo_translate(cr, 40, 40);
+  cairo_set_source_rgb(cr, 0.3, 0.8, 0.8);
+  cairo_rectangle(cr, 0, 0, 30, 30);
+  cairo_fill(cr);    
+}
+```
+The examle draws a rectangle. Then we do a translation and draw the same rectangle again.
+
+```cpp
+cairo_translate(cr, 20, 20);
+```
+The cairo_translate() function modifies the current transormation matrix by translating the user space origin. In our case we shift the origin by 20 units in both directions.
+
+(Translation) Figure: Translation
+
+## Shear
+In the following example, we perform a shearing operation. A shearing is an object distortion along a particular axis. There is no shear function for this operation. We need to create our own transformation matrix. Note that each affine transformation can be performed by creating a transformation matrix.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{  
+  cairo_matrix_t matrix;
+
+  cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
+  cairo_rectangle(cr, 20, 30, 80, 50);
+  cairo_fill(cr);
+  cairo_matrix_init(&matrix,
+      1.0, 0.5,
+      0.0, 1.0,
+      0.0, 0.0);
+
+  cairo_transform(cr, &matrix);
+  cairo_rectangle(cr, 130, 30, 80, 50);
+  cairo_fill(cr);
+}
+```
+In this code example, we perform a simple shearing operation.
+
+```cpp
+cairo_matrix_t matrix;
+```
+The cairo_matrix_t is a structure that holds an affine transformation.
+
+```cpp
+cairo_matrix_init(&matrix,
+    1.0, 0.5,
+    0.0, 1.0,
+    0.0, 0.0);
+```
+This transformation shears y values by 0.5 of the x values.
+
+```cpp
+cairo_transform(cr, &matrix);
+```
+We perform the transformation with the transform() method.
+
+(Shearing) Figure: Shearing
+
+## Scaling
+The next example demonstrates a scaling operation. Scaling is a transformation operation where the object is enlarged or shrunken.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{        
+  cairo_set_source_rgb(cr, 0.2, 0.3, 0.8);
+  cairo_rectangle(cr, 10, 10, 90, 90);    
+  cairo_fill(cr);
+  
+  cairo_scale(cr, 0.6, 0.6);
+  cairo_set_source_rgb(cr, 0.8, 0.3, 0.2);
+  cairo_rectangle(cr, 30, 30, 90, 90);    
+  cairo_fill(cr);  
+
+  cairo_scale(cr, 0.8, 0.8);
+  cairo_set_source_rgb(cr, 0.8, 0.8, 0.2);
+  cairo_rectangle(cr, 50, 50, 90, 90);    
+  cairo_fill(cr);      
+}
+```
+We draw three rectangles of 90x90px size. On two of them, we perform a scaling operation.
+
+```cpp
+cairo_scale(cr, 0.6, 0.6);
+cairo_set_source_rgb(cr, 0.8, 0.3, 0.2);
+cairo_rectangle(cr, 30, 30, 90, 90);    
+cairo_fill(cr);
+```
+We uniformly scale a rectangle by a factor of 0.6.
+
+```cpp
+cairo_scale(cr, 0.8, 0.8);
+cairo_set_source_rgb(cr, 0.8, 0.8, 0.2);
+cairo_rectangle(cr, 50, 50, 90, 90);    
+cairo_fill(cr); 
+```
+Here we perform another scaling operation by a factor of 0.8. If we look at the picture, we see that the third yellow rectangle is the smallest one. Even if we have used a smaller scaling factor. This is because transformation operations are additive. In fact, the third rectangle was scaled by a factor of 0.528 (0.6x0.8).
+
+(Scaling) Figure: Scaling
+
+## Isolating transformations
+Transformation operations are additive. To isolate one operation from the other one, we can use the cairo_save() and cairo_restore() functions. The cairo_save() function makes a copy of the current state of the drawing context and saves it on an internal stack of saved states. The cairo_restore() function will re-establish the context to the saved state.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{     
+  cairo_set_source_rgb(cr, 0.2, 0.3, 0.8);
+  cairo_rectangle(cr, 10, 10, 90, 90);    
+  cairo_fill(cr);
+  
+  cairo_save(cr);
+  cairo_scale(cr, 0.6, 0.6);
+  cairo_set_source_rgb(cr, 0.8, 0.3, 0.2);
+  cairo_rectangle(cr, 30, 30, 90, 90);    
+  cairo_fill(cr);
+  cairo_restore(cr);
+
+  cairo_save(cr);
+  cairo_scale(cr, 0.8, 0.8);
+  cairo_set_source_rgb(cr, 0.8, 0.8, 0.2);
+  cairo_rectangle(cr, 50, 50, 90, 90);    
+  cairo_fill(cr);        
+  cairo_restore(cr);
+}
+```
+In the example we scale two rectangles. This time we isolate the scaling operations from each other.
+
+```cpp
+cairo_save(cr);
+cairo_scale(cr, 0.6, 0.6);
+cairo_set_source_rgb(cr, 0.8, 0.3, 0.2);
+cairo_rectangle(cr, 30, 30, 90, 90);    
+cairo_fill(cr);
+cairo_restore(cr);
+```
+We isolate the scaling operation by putting the cairo_scale() function between the cairo_save() and cairo_restore() functions.
+
+(Isolating transformations) Figure: Isolating transformations
+
+Now the third yellow rectangle is bigger than the second red one.
+
+## Donut
+In the following example we create an complex shape by rotating a bunch of ellipses.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <math.h>
+
+
+static void do_drawing(cairo_t *, GtkWidget *widget);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{        
+  do_drawing(cr, widget);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{         
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+
+  cairo_set_line_width(cr, 0.5);
+  cairo_translate(cr, width/2, height/2);
+  cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);
+  cairo_stroke(cr);
+
+  gint i;
+  for (i = 0; i < 36; i++) {
+      cairo_save(cr);
+      cairo_rotate(cr, i*M_PI/36);
+      cairo_scale(cr, 0.3, 1);
+      cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);
+      cairo_restore(cr);
+      cairo_stroke(cr);      
+  }    
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL);
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 350, 250); 
+  gtk_window_set_title(GTK_WINDOW(window), "Donut");
+  
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+We will do rotation and scaling operations. We will also save and restore Cairo contexts.
+
+```cpp
+cairo_translate(cr, width/2, height/2);
+cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);
+cairo_stroke(cr);
+```
+In the middle of the GTK+ window, we create a circle. This will be a bounding circle for our ellipses.
+
+```cpp
+gint i;
+for (i = 0; i < 36; i++) {
+    cairo_save(cr);
+    cairo_rotate(cr, i*M_PI/36);
+    cairo_scale(cr, 0.3, 1);
+    cairo_arc(cr, 0, 0, 120, 0, 2 * M_PI);
+    cairo_restore(cr);
+    cairo_stroke(cr);      
+}
+```
+We create 36 ellipses along the path of our bounding circle. We insulate each rotate and scale operation from one another with the cairo_save() and cairo_restore() methods.
+
+## Star
+The next example shows a rotating and scaling star.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *, GtkWidget *widget);
+
+int points[11][2] = { 
+    { 0, 85 }, 
+    { 75, 75 }, 
+    { 100, 10 }, 
+    { 125, 75 }, 
+    { 200, 85 },
+    { 150, 125 }, 
+    { 160, 190 },
+    { 100, 150 }, 
+    { 40, 190 },
+    { 50, 125 },
+    { 0, 85 } 
+};
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr, widget);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  static gdouble angle = 0;
+  static gdouble scale = 1;
+  static gdouble delta = 0.01;
+
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint width, height;
+  gtk_window_get_size(GTK_WINDOW(win), &width, &height);
+
+  cairo_set_source_rgb(cr, 0, 0.44, 0.7);
+  cairo_set_line_width(cr, 1);
+
+  cairo_translate(cr, width/2, height/2 );
+  cairo_rotate(cr, angle);
+  cairo_scale(cr, scale, scale);
+
+  gint i;
+
+  for ( i = 0; i < 10; i++ ) {
+      cairo_line_to(cr, points[i][0], points[i][1]);
+  }
+
+  cairo_close_path(cr);
+  cairo_fill(cr);
+  cairo_stroke(cr);
+
+  if ( scale < 0.01 ) {
+      delta = -delta;
+  } else if (scale > 0.99) {
+      delta = -delta;
+  }
+
+  scale += delta;
+  angle += 0.01;    
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{
+  gtk_widget_queue_draw(widget);
+  
+  return TRUE;
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);  
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+ 
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 400, 300); 
+  gtk_window_set_title(GTK_WINDOW(window), "Star");
+
+  g_timeout_add(10, (GSourceFunc) time_handler, (gpointer) window);  
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+In this example, we create a star object. We will translate it, rotate it, and scale it.
+
+```cpp
+int points[11][2] = { 
+    { 0, 85 }, 
+    { 75, 75 }, 
+    { 100, 10 }, 
+...
+```
+The star object will be constructed from these points.
+
+```cpp
+static gdouble angle = 0;
+static gdouble scale = 1;
+static gdouble delta = 0.01;
+```
+We initialize three important variables. The angle is used in the rotation, the scale in scaling the star object. The delta variable controls when the star is growing and when it is shrinking.
+
+```cpp
+cairo_translate(cr, width/2, height/2);
+cairo_rotate(cr, angle);
+cairo_scale(cr, scale, scale);
+```
+We shift the star into the middle of the window. Rotate it and scale it.
+
+```cpp
+gint i;
+for ( i = 0; i < 10; i++ ) {
+    cairo_line_to(cr, points[i][0], points[i][1]);
+}
+
+cairo_close_path(cr);
+cairo_fill(cr);
+cairo_stroke(cr);
+```
+Here we draw the star object.
+
+```cpp
+if ( scale < 0.01 ) {
+    delta = -delta;
+} else if (scale > 0.99) {
+    delta = -delta;
+}
+```
+These lines control the growing or shrinking of the star object.
+
+In this part of the Cairo graphics tutorial, we talked about transformations.
\ No newline at end of file
diff --git a/src/12-cairotext.md b/src/12-cairotext.md
new file mode 100644
index 0000000..af17749
--- /dev/null
+++ b/src/12-cairotext.md
@@ -0,0 +1,247 @@
+# Text in Cairo
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will work with text.
+
+## Soulmate
+In the first example, we will display some lyrics on the GTK+ window.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgb(cr, 0.1, 0.1, 0.1); 
+
+  cairo_select_font_face(cr, "Purisa",
+      CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_BOLD);
+
+  cairo_set_font_size(cr, 13);
+
+  cairo_move_to(cr, 20, 30);
+  cairo_show_text(cr, "Most relationships seem so transitory");  
+  cairo_move_to(cr, 20, 60);
+  cairo_show_text(cr, "They're all good but not the permanent one");
+
+  cairo_move_to(cr, 20, 120);
+  cairo_show_text(cr, "Who doesn't long for someone to hold");
+
+  cairo_move_to(cr, 20, 150);
+  cairo_show_text(cr, "Who knows how to love you without being told");
+  cairo_move_to(cr, 20, 180);
+  cairo_show_text(cr, "Somebody tell me why I'm on my own");
+  cairo_move_to(cr, 20, 210);
+  cairo_show_text(cr, "If there's a soulmate for everyone");    
+}
+```
+In this example, we display part of the lyrics from the Natasha Bedingfield's Soulmate song.
+
+```cpp
+cairo_select_font_face(cr, "Purisa",
+   CAIRO_FONT_SLANT_NORMAL,
+   CAIRO_FONT_WEIGHT_BOLD);
+```
+Here we select the font face. The function takes three parameters, the font family, font slant and the font weight.
+
+```cpp
+cairo_set_font_size(cr, 13);
+```
+Here we specify the font size.
+
+```cpp
+cairo_move_to(cr, 20, 30);
+cairo_show_text(cr, "Most relationships seem so transitory"); 
+```
+We display the text on the window by specifying the position of the text and calling the cairo_show_text() function.
+
+(Soulmate) Figure: Soulmate
+
+## Centered text
+Next we will show, how to center text on the window.
+
+```cpp
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  cairo_text_extents_t extents;
+  
+  GtkWidget *win = gtk_widget_get_toplevel(widget);
+  
+  gint w, h;
+  gtk_window_get_size(GTK_WINDOW(win), &w, &h);    
+
+  cairo_select_font_face(cr, "Courier",
+      CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_BOLD);
+
+  cairo_set_font_size(cr, 60);
+  
+  cairo_text_extents(cr, "ZetCode", &extents);
+
+  cairo_move_to(cr, w/2 - extents.width/2, h/2);  
+  cairo_show_text(cr, "ZetCode");    
+}
+```
+The code will center a text on the window. It remains centered, even if we resize the window.
+
+```cpp
+GtkWidget *win = gtk_widget_get_toplevel(widget);
+
+gint w, h;
+gtk_window_get_size(GTK_WINDOW(win), &w, &h);
+```
+To center a text on the window, it is necessary to get the size of of the parent window.
+
+```cpp
+cairo_select_font_face(cr, "Courier",
+    CAIRO_FONT_SLANT_NORMAL,
+    CAIRO_FONT_WEIGHT_BOLD);
+
+cairo_set_font_size(cr, 60);
+```
+We select a font and its size to be displayed.
+
+```cpp
+cairo_text_extents(cr, "ZetCode", &extents);
+```
+We get the text extents. These are some numbers that describe the text. We need the width of the text for our example.
+
+```cpp
+cairo_move_to(cr, w/2 - extents.width/2, h/2);  
+cairo_show_text(cr, "ZetCode");
+```
+We position the text into the middle of the window and show it using the cairo_show_text() method.
+
+(Centered text) Figure: Centered text
+
+## Shaded text
+Now we will show a shaded text on the window.
+
+```cpp
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_BOLD);
+  cairo_set_font_size(cr, 50);
+
+  cairo_set_source_rgb(cr, 0, 0, 0);
+  cairo_move_to(cr, 40, 60);  
+  cairo_show_text(cr, "ZetCode");  
+  
+  cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
+  cairo_move_to(cr, 43, 63);  
+  cairo_show_text(cr, "ZetCode");    
+}
+```
+To create a shade, we draw the text twice. In different colours. The second text is moved a bit to the right and bottom.
+
+```cpp
+cairo_set_source_rgb(cr, 0, 0, 0);
+cairo_move_to(cr, 40, 60);  
+cairo_show_text(cr, "ZetCode"); 
+```
+The first text is drawn in black ink. It serves as a shade.
+
+```cpp
+cairo_set_source_rgb(cr, 0.5, 0.5, 0.5);
+cairo_move_to(cr, 43, 63);  
+cairo_show_text(cr, "ZetCode");
+```
+The second text is drawn in some gray ink. It is moved by 3px to the right and to the bottom.
+
+(Shaded text) Figure: Shaded text
+
+## Text filled with gradient
+The following example will create a nice effect. We will fill a text with some linear gradient.
+
+```cpp
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{  
+  cairo_pattern_t *pat; 
+  
+  cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
+  cairo_paint(cr);
+  
+  gint h = 90;
+  
+  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_ITALIC, 
+      CAIRO_FONT_WEIGHT_BOLD);
+  cairo_set_font_size(cr, h);
+  
+  pat = cairo_pattern_create_linear(0, 15, 0, h*0.8);
+  cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
+  cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0);
+  cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
+                  
+  cairo_move_to(cr, 15, 80);
+  cairo_text_path(cr, "ZetCode");
+  cairo_set_source(cr, pat);
+  cairo_fill(cr);
+}
+```
+We draw a text on the window filled with a linear gradient. The colours are some orange colours.
+
+```cpp
+cairo_set_source_rgb(cr, 0.2, 0.2, 0.2);
+cairo_paint(cr);
+```
+To make it more visually appealing, we paint the background in dark gray colour.
+
+```cpp
+pat = cairo_pattern_create_linear(0, 15, 0, h*0.8);
+cairo_pattern_set_extend(pat, CAIRO_EXTEND_REPEAT);
+cairo_pattern_add_color_stop_rgb(pat, 0.0, 1, 0.6, 0);
+cairo_pattern_add_color_stop_rgb(pat, 0.5, 1, 0.3, 0);
+```
+The linear gradient is created.
+
+```cpp
+cairo_move_to(cr, 15, 80);
+cairo_text_path(cr, "ZetCode");
+cairo_set_source(cr, pat);
+cairo_fill(cr);
+```
+The text is displayed on the window. We use the gradient as a source for painting.
+
+(Text filled with gradient) Figure: Text filled with gradient
+
+## Glyphs
+The cairo_show_text() method is only suitable for simple text rendering. Cairo developers call it a toy method. More professional text rendering is done with glyphs. A glyph is a graphic symbol which provides a form for a character. A character provides a meaning. It can have multiple glyphs. A character has no intrinsic appearance. A glyph has no intrinsic meaning.
+
+Note that many common programming requirements conserning text are addressed by the Pango library.
+
+```cpp
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{    
+  cairo_select_font_face(cr, "Serif", CAIRO_FONT_SLANT_NORMAL,
+      CAIRO_FONT_WEIGHT_NORMAL);
+  cairo_set_font_size(cr, 13);
+
+  const int n_glyphs = 20 * 35;
+  cairo_glyph_t glyphs[n_glyphs];
+
+  gint i = 0;  
+  gint x, y;
+  
+  for (y=0; y<20; y++) {
+      for (x=0; x<35; x++) {
+          glyphs[i] = (cairo_glyph_t) {i, x*15 + 20, y*18 + 20};
+          i++;
+      }
+  }
+  
+  cairo_show_glyphs(cr, glyphs, n_glyphs);
+} 
+```
+This code shows 700 glyphs of a chosen font.
+
+```cpp
+const int n_glyphs = 20 * 35;
+cairo_glyph_t glyphs[n_glyphs];
+```
+The glyphs array will store three integer values. The first value is the index of the glyph to the chosen font type. The second and the third values are x, y positions of a glyph.
+
+```cpp
+cairo_show_glyphs(cr, glyphs, n_glyphs);
+```
+The cairo_show_glyphs() method shows the glyphs on the window.
+
+This chapter covered text in Cairo.
\ No newline at end of file
diff --git a/src/13-cairoimages.md b/src/13-cairoimages.md
new file mode 100644
index 0000000..4e8dca5
--- /dev/null
+++ b/src/13-cairoimages.md
@@ -0,0 +1,365 @@
+# Images in Cairo
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will talk about the images. We will show how to display an image on the GTK window. We will also create some effects with images.
+
+## Displaying an image
+In the first example, we will display an image.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+struct {
+  cairo_surface_t *image;  
+} glob;
+
+
+static void do_drawing(cairo_t *);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_surface(cr, glob.image, 10, 10);
+  cairo_paint(cr);    
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+  
+  glob.image = cairo_image_surface_create_from_png("stmichaelschurch.png");
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK (gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 300, 220); 
+  gtk_window_set_title(GTK_WINDOW(window), "Image");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  cairo_surface_destroy(glob.image);
+
+  return 0;
+}
+```
+The example displays an image.
+
+```cpp
+glob.image = cairo_image_surface_create_from_png("stmichaelschurch.png");
+```
+We create an image surface from a PNG image. For efficiency reasons, the function is called in the main function.
+
+```cpp
+cairo_set_source_surface(cr, glob.image, 10, 10);
+```
+We create a source for painting from the created image surface.
+
+```cpp
+cairo_paint(cr);   
+```
+We paint the source on the window.
+
+```cpp
+cairo_surface_destroy(glob.image);
+```
+In the end, the surface is destroyed.
+
+## Watermark
+It is common to draw information on images. The text written on an image is called a watermark. Watermarks are used to identify images. They could be copyright notices or image creation times.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *, GtkWidget *widget);
+
+struct {
+  cairo_surface_t *image;  
+} glob;
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr, widget);  
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  cairo_set_source_surface(cr, glob.image, 10, 10);
+  cairo_paint(cr);
+}
+
+static void load_image()
+{        
+  glob.image = cairo_image_surface_create_from_png("beckov.png"); 
+}
+
+static void draw_mark() 
+{ 
+  cairo_t *ic;
+  ic = cairo_create(glob.image);
+  cairo_set_font_size(ic, 11);
+  
+  cairo_set_source_rgb(ic, 0.9 , 0.9 , 0.9);
+  cairo_move_to(ic, 20, 30);
+  cairo_show_text(ic, " Beckov 2012 , (c) Jan Bodnar ");
+  cairo_stroke(ic);   
+}
+
+int main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+  
+  load_image();
+  draw_mark();
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 350, 250); 
+  gtk_window_set_title(GTK_WINDOW(window), "Watermark");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+  
+  cairo_surface_destroy(glob.image);
+
+  return 0;
+}
+```
+
+We draw copyright information on an image.
+
+```cpp
+static void load_image()
+{        
+  glob.image = cairo_image_surface_create_from_png("beckov.png"); 
+}
+```
+In the load_image() method, we create an image surface from a PNG image.
+
+```cpp
+static void draw_mark() 
+{ 
+  cairo_t *ic;
+  ic = cairo_create(glob.image);
+...
+```
+In the draw_mark() function, we draw the copyright message on the image. First we create a drawing context from the image surface.
+
+```cpp
+cairo_set_font_size(ic, 11);
+
+cairo_set_source_rgb(ic, 0.9 , 0.9 , 0.9);
+cairo_move_to(ic, 20, 30);
+cairo_show_text(ic, " Beckov 2012 , (c) Jan Bodnar ");
+cairo_stroke(ic);   
+```
+Then we draw a small text in white colour.
+
+```cpp
+static void do_drawing(cairo_t *cr, GtkWidget *widget)
+{
+  cairo_set_source_surface(cr, glob.image, 10, 10);
+  cairo_paint(cr);
+}
+```
+The image surface is drawn on the window.
+
+## The spectrum effect
+We call this a spectrum effect, because it resembles and old ZX Spectrum computer. When you were loading an image into this computer, it was gradually appearing on the screen. The next example is loosely based on this experience.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+struct {
+  gboolean timer;
+  cairo_surface_t *image;
+  cairo_surface_t *surface;
+  gint img_width;
+  gint img_height;
+} glob;
+
+
+static void init_vars()
+{
+  glob.image = cairo_image_surface_create_from_png("beckov.png");
+  
+  glob.img_width = cairo_image_surface_get_width(glob.image);
+  glob.img_height = cairo_image_surface_get_height(glob.image);  
+  
+  glob.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
+      glob.img_width, glob.img_height);    
+  glob.timer = TRUE;   
+}
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);
+  
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_t *ic;
+
+  static gint count = 0;
+
+  ic = cairo_create(glob.surface);
+
+  gint i, j;
+  for (i = 0; i <= glob.img_height; i+=7) {
+      for (j = 0 ; j < count; j++) {
+          cairo_move_to(ic, 0, i+j);
+          cairo_line_to(ic, glob.img_width, i+j);
+      }
+  }
+
+  count++;
+  if (count == 8) glob.timer = FALSE;
+
+  cairo_set_source_surface(cr, glob.image, 10, 10);
+  cairo_mask_surface(cr, glob.surface, 10, 10);
+  cairo_stroke(ic);
+
+  cairo_destroy(ic);  
+}
+
+static gboolean time_handler(GtkWidget *widget)
+{
+  if (!glob.timer) return FALSE;
+
+  gtk_widget_queue_draw(widget);
+  return TRUE;
+}
+
+
+int main(int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  init_vars();
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(G_OBJECT(window), "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 325, 250); 
+  gtk_window_set_title(GTK_WINDOW(window), "Spectrum");
+
+  g_timeout_add(400, (GSourceFunc) time_handler, (gpointer) window);
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  cairo_surface_destroy(glob.image);
+  cairo_surface_destroy(glob.surface);  
+
+  return 0;
+}
+```
+We divide the image into n parts consisting of 8 lines. Each cycle each part of the image will get bigger by one pixel. The created image will serve as a mask for displaying the image of the castle.
+
+```cpp
+struct {
+  gboolean timer;
+  cairo_surface_t *image;
+  cairo_surface_t *surface;
+  gint img_width;
+  gint img_height;
+} glob;
+```
+The glob structure stores variables that are used within more functions.
+
+```cpp
+static void init_vars()
+{
+  glob.image = cairo_image_surface_create_from_png("beckov.png");
+  
+  glob.img_width = cairo_image_surface_get_width(glob.image);
+  glob.img_height = cairo_image_surface_get_height(glob.image);  
+  
+  glob.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 
+      glob.img_width, glob.img_height);    
+  glob.timer = TRUE;   
+}
+```
+In the init_vars() function, we initiate the aforementioned variables.
+
+```cpp
+gint i, j;
+for (i = 0; i <= glob.img_height; i+=7) {
+    for (j = 0 ; j < count; j++) {
+        cairo_move_to(ic, 0, i+j);
+        cairo_line_to(ic, glob.img_width, i+j);
+    }
+}
+```
+We gradully draw lines into each of the n parts.
+
+```cpp
+count++;
+if (count == 8) glob.timer = FALSE;
+```
+After 8 steps, the animation finishes.
+
+```cpp
+cairo_set_source_surface(cr, glob.image, 10, 10);
+cairo_mask_surface(cr, glob.surface, 10, 10);
+cairo_stroke(ic);
+```
+Using the mask operation, we draw the portions of the image on the window.
+
+This chapter covered images in Cairo.
\ No newline at end of file
diff --git a/src/14-root.md b/src/14-root.md
new file mode 100644
index 0000000..88853d0
--- /dev/null
+++ b/src/14-root.md
@@ -0,0 +1,329 @@
+# Root window
+last modified July 13, 2020
+
+In this part of the Cairo graphics tutorial, we will work with the root window. The root window is the desktop window where we usually have icon shortcuts.
+
+It is possible to manipulate with the root window. From the programmer's perspective, it is just a special kind of a window.
+
+## Transparent window
+Our first example will create a transparent window. We will see, what it beneath of the window object.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+
+static void do_drawing(cairo_t *);
+
+
+static void tran_setup(GtkWidget *win)
+{        
+  GdkScreen *screen;
+  GdkVisual *visual;
+  
+  gtk_widget_set_app_paintable(win, TRUE);
+  screen = gdk_screen_get_default();
+  visual = gdk_screen_get_rgba_visual(screen);
+  
+  if (visual != NULL && gdk_screen_is_composited(screen)) {
+      gtk_widget_set_visual(win, visual);
+  }
+}
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);  
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.4);
+  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint(cr);
+}
+
+int main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *darea;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  
+  tran_setup(window);
+
+  darea = gtk_drawing_area_new();
+  gtk_container_add(GTK_CONTAINER (window), darea);
+
+  g_signal_connect(G_OBJECT(darea), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 300, 250); 
+  gtk_window_set_title(GTK_WINDOW(window), "Transparent window");
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+To create a transparent window, we get the visual of the screen object and set it for our window. In the on_draw() method, we draw over the screen's visual object. This creates an illusion of partial transparency.
+
+```cpp
+gtk_widget_set_app_paintable(win, TRUE);
+```
+We must set the application to be painted on.
+
+```cpp
+screen = gdk_screen_get_default();
+```
+The gdk_screen_get_default() method returns the screen object.
+
+```cpp
+visual = gdk_screen_get_rgba_visual(screen);
+```
+From the screen window, we get its visual. The visual contains the low level display information.
+
+```cpp
+if (visual != NULL && gdk_screen_is_composited(screen)) {
+    gtk_widget_set_visual(win, visual);
+}
+```
+Not all displays support this operation. Therefore, we check if our screen supports composition and the returned visual is not None. We set the screen's visual to be the visual of our window.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+  cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 0.4);
+  cairo_set_operator(cr, CAIRO_OPERATOR_SOURCE);
+  cairo_paint(cr);
+}
+```
+We use a partially transparent source to draw over the screen window. The CAIRO_OPERATOR_SOURCE creates a composition operation where we draw over the source. Which is the screen window. To get full transparency, we set the alpha value to 0 or use the CAIRO_OPERATOR_CLEAR operator.
+
+(Transparent window) Figure: Transparent window
+
+## Taking a screenshot
+The root window is also essential in taking a screenshot.
+
+```cpp
+#include <cairo.h>
+#include <gdk/gdk.h>
+
+int main (int argc, char *argv[])
+{
+  gdk_init(&argc, &argv);
+  
+  GdkWindow *root_win = gdk_get_default_root_window();
+  gint width = gdk_window_get_width(root_win);
+  gint height = gdk_window_get_height(root_win);
+
+  cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+      width, height);
+    
+  GdkPixbuf *pb = gdk_pixbuf_get_from_window(root_win, 0, 0, width, height);
+
+  cairo_t *cr = cairo_create(surface);        
+  gdk_cairo_set_source_pixbuf(cr, pb, 0, 0);  
+  cairo_paint(cr);  
+
+  cairo_surface_write_to_png(surface, "image.png");
+  
+  cairo_destroy(cr);
+  cairo_surface_destroy(surface);
+
+  return 0;
+}
+```
+The example captures a snapshot of the entire screen. In this example, we do not use the full GTK windowing system. We use Cairo and GDK libraries to do the job.
+
+```cpp
+gdk_init(&argc, &argv);
+```
+The gdk_init() initializes the GDK library and connects to the windowing system.
+
+```cpp
+GdkWindow *root_win = gdk_get_default_root_window();
+```
+We get the root window with the gdk_get_default_root_window() function call.
+
+```cpp
+gint width = gdk_window_get_width(root_win);
+gint height = gdk_window_get_height(root_win);
+```
+We determine the width and the height of the root window.
+
+```cpp
+cairo_surface_t *surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+    width, height);
+```
+An empty image surface is created. It has the size of the root window.
+
+```cpp
+GdkPixbuf *pb = gdk_pixbuf_get_from_window(root_win, 0, 0, width, height);
+```
+We get a pixbuf from the root window using the gdk_pixbuf_get_from_window() function call. A pixbuf is an object that describes an image in memory.
+
+```cpp
+cairo_t *cr = cairo_create(surface);        
+gdk_cairo_set_source_pixbuf(cr, pb, 0, 0);  
+cairo_paint(cr);
+```
+In the above code lines, we create a Cairo drawing context on the image surface that we have created earlier. We place the pixbuf on the drawing context and paint it on the surface.
+
+```cpp
+cairo_surface_write_to_png(surface, "image.png");
+```
+The image surface is written to a PNG image using the write_to_png() method.
+
+```cpp
+cairo_destroy(cr);
+cairo_surface_destroy(surface);
+```
+We clean up resources.
+
+## Showing a message
+In the third example, we will show a message on the desktop window.
+
+```cpp
+#include <cairo.h>
+#include <gtk/gtk.h>
+#include <pango/pango.h>
+
+static void do_drawing(cairo_t *);
+
+static gboolean on_draw_event(GtkWidget *widget, cairo_t *cr, 
+    gpointer user_data)
+{      
+  do_drawing(cr);  
+
+  return FALSE;
+}
+
+static void do_drawing(cairo_t *cr)
+{
+   cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+   cairo_paint(cr);
+   cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+}
+
+static void setup(GtkWidget *win)
+{        
+  gtk_widget_set_app_paintable(win, TRUE);
+  gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DOCK);
+  gtk_window_set_keep_below(GTK_WINDOW(win), TRUE);
+  
+  GdkScreen *screen = gdk_screen_get_default();
+  GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
+  
+  if (visual != NULL && gdk_screen_is_composited(screen)) {
+      gtk_widget_set_visual(win, visual);
+  }  
+}
+
+int main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *lbl;
+
+  gtk_init(&argc, &argv);
+
+  window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+  
+  setup(window);
+  
+  lbl = gtk_label_new("ZetCode, tutorials for programmers");
+  
+  PangoFontDescription *fd = pango_font_description_from_string("Serif 20");
+  gtk_widget_modify_font(lbl, fd);  
+  gtk_container_add(GTK_CONTAINER(window), lbl);  
+  
+  GdkColor color;
+  gdk_color_parse("white", &color);
+  gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, &color);
+  
+  g_signal_connect(G_OBJECT(window), "draw", 
+      G_CALLBACK(on_draw_event), NULL); 
+  g_signal_connect(window, "destroy",
+      G_CALLBACK(gtk_main_quit), NULL);
+
+  gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+  gtk_window_set_default_size(GTK_WINDOW(window), 350, 250); 
+
+  gtk_widget_show_all(window);
+
+  gtk_main();
+
+  return 0;
+}
+```
+The code displays a message label on the root window.
+
+```cpp
+static void do_drawing(cairo_t *cr)
+{
+   cairo_set_operator(cr, CAIRO_OPERATOR_CLEAR);
+   cairo_paint(cr);
+   cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
+}
+```
+We use the CAIRO_OPERATOR_CLEAR operator to clear the background of the window. Then we set the CAIRO_OPERATOR_OVER to let the label widget be drawn.
+
+```cpp
+gtk_widget_set_app_paintable(win, TRUE);
+```
+We will be manipulating the application window, so we make it paintable.
+
+```cpp
+gtk_window_set_type_hint(GTK_WINDOW(win), GDK_WINDOW_TYPE_HINT_DOCK);
+```
+Implementing this window hint removes window borders and decoration.
+
+```cpp
+gtk_window_set_keep_below(GTK_WINDOW(win), TRUE);
+```
+We keep the application always at the bottom, just over the root window.
+
+```cpp
+GdkScreen *screen = gdk_screen_get_default();
+GdkVisual *visual = gdk_screen_get_rgba_visual(screen);
+
+if (visual != NULL && gdk_screen_is_composited(screen)) {
+    gtk_widget_set_visual(win, visual);
+}
+```
+We set the visual of the screen to be the visual of our application.
+
+```cpp
+lbl = gtk_label_new("ZetCode, tutorials for programmers");
+```
+We create a message label.
+
+```cpp
+PangoFontDescription *fd = pango_font_description_from_string("Serif 20");
+gtk_widget_modify_font(lbl, fd);
+```
+With the help of the Pango module, we select a specific font for the text.
+
+```cpp
+gtk_container_add(GTK_CONTAINER(window), lbl);
+```
+The label is put onto the window.
+
+```cpp
+GdkColor color;
+gdk_color_parse("white", &color);
+gtk_widget_modify_fg(lbl, GTK_STATE_NORMAL, &color);
+```
+We modify the text to be in white colour.
+
+(Message on the root window) Figure: Message on the root window
+
+In this chapter we have worked with the desktop window in Cairo.
\ No newline at end of file

From b468be17b3e699dd28c73fd7dfba099fe05aeead Mon Sep 17 00:00:00 2001
From: Victor Dudochkin <dudochkin.victor@gmail.com>
Date: Mon, 12 Apr 2021 17:48:11 +0700
Subject: [PATCH 4/4] Test workflow

---
 .github/workflows/documentation.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/documentation.yml b/.github/workflows/documentation.yml
index ea331d1..18e8e9f 100644
--- a/.github/workflows/documentation.yml
+++ b/.github/workflows/documentation.yml
@@ -2,7 +2,7 @@
 
 # On every push this script is executed
 
-name: Publish documentation
+name: Documentation
 
 on:
   push:
