You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@training.apache.org by la...@apache.org on 2019/05/17 10:20:15 UTC
[incubator-training] 01/01: Initial version for TRAINING-13 with
content for ZooKeeper in English and German
This is an automated email from the ASF dual-hosted git repository.
larsfrancke pushed a commit to branch TRAINING-13
in repository https://gitbox.apache.org/repos/asf/incubator-training.git
commit dd20b803b87be2e67ec0d5414062359ba92b853e
Author: Lars Francke <la...@gmail.com>
AuthorDate: Fri May 17 12:19:57 2019 +0200
Initial version for TRAINING-13 with content for ZooKeeper in English and German
Signed-off-by: Lars Francke <la...@gmail.com>
---
content/.gitkeep | 0
content/ZooKeeper/README.md | 49 +++
.../ZooKeeper/libs/docinfo-hack/document.html.slim | 214 +++++++++++++
content/ZooKeeper/pom.xml | 289 +++++++++++++++++
content/ZooKeeper/src/main/asciidoc/index_de.adoc | 116 +++++++
content/ZooKeeper/src/main/asciidoc/index_en.adoc | 116 +++++++
.../src/main/resources/images/data-model.graffle | Bin 0 -> 3801 bytes
.../src/main/resources/images/data-model.png | Bin 0 -> 124127 bytes
content/ZooKeeper/src/main/theme/apache.css | 349 +++++++++++++++++++++
9 files changed, 1133 insertions(+)
diff --git a/content/.gitkeep b/content/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/content/ZooKeeper/README.md b/content/ZooKeeper/README.md
new file mode 100644
index 0000000..cdcd8f6
--- /dev/null
+++ b/content/ZooKeeper/README.md
@@ -0,0 +1,49 @@
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+
+# Apache ZooKeeper
+
+This directory contains a brief introduction into Apache ZooKeeper.
+
+
+## Building the presentation
+
+By running the following command, you can generate the presentation:
+
+ mvn clean package
+
+## Running the presentation
+
+In order to start a local web server serving the presentation, execute the following command:
+
+ mvn jetty:run-exploded
+
+As soon as that's done, just point your browser to:
+
+ http://localhost:8080/
+
+## Generating PDF versions
+
+In order to generate a PDF version of the presentation just add `?print-pdf` to the url. (Keep in mind, that you have to add it before any `#blahblah`)
+
+The following link should do the trick:
+
+ http://localhost:8080/?print-pdf
+
+As soon as that's loaded, just use the normal `print` functionality of the browser and `print as PDF`.
diff --git a/content/ZooKeeper/libs/docinfo-hack/document.html.slim b/content/ZooKeeper/libs/docinfo-hack/document.html.slim
new file mode 100644
index 0000000..ec9e3cf
--- /dev/null
+++ b/content/ZooKeeper/libs/docinfo-hack/document.html.slim
@@ -0,0 +1,214 @@
+doctype 5
+html lang=(attr :lang, 'en' unless attr? :nolang)
+ head
+ meta charset="utf-8"
+ - revealjsdir = (attr :revealjsdir, 'reveal.js')
+ - unless (asset_uri_scheme = (attr 'asset-uri-scheme', 'https')).empty?
+ - asset_uri_scheme = %(#{asset_uri_scheme}:)
+ - cdn_base = %(#{asset_uri_scheme}//cdnjs.cloudflare.com/ajax/libs)
+ - [:description, :keywords, :author, :copyright].each do |key|
+ - if attr? key
+ meta name=key content=(attr key)
+ title=(doctitle sanitize: true, use_fallback: true)
+ meta content="yes" name="apple-mobile-web-app-capable"
+ meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"
+ meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui" name="viewport"
+ link href="#{revealjsdir}/css/reveal.css" rel="stylesheet"
+ link href="css/c3.min.css" rel="stylesheet"
+ script src="js/d3.min.js" charset="utf-8"
+ script src="js/c3.min.js"
+ / Default theme required even when using custom theme
+ - if attr? :revealjs_customtheme
+ link rel='stylesheet' href=(attr :revealjs_customtheme) id='theme'
+ - else
+ link rel='stylesheet' href='#{revealjsdir}/css/theme/#{attr 'revealjs_theme', 'black'}.css' id='theme'
+ - if attr? :icons, 'font'
+ - if attr? 'iconfont-remote'
+ link rel='stylesheet' href=(attr 'iconfont-cdn', %(#{cdn_base}/font-awesome/4.3.0/css/font-awesome.min.css))
+ - else
+ link rel='stylesheet' href=(normalize_web_path %(#{attr 'iconfont-name', 'font-awesome'}.css), (attr 'stylesdir', ''), false)
+ - if attr? :stem
+ - eqnums_val = (attr 'eqnums', 'none')
+ - eqnums_val = 'AMS' if eqnums_val == ''
+ - eqnums_opt = %( equationNumbers: { autoNumber: "#{eqnums_val}" } )
+ script type='text/x-mathjax-config'
+ | MathJax.Hub.Config({
+ tex2jax: {
+ inlineMath: [#{Asciidoctor::INLINE_MATH_DELIMITERS[:latexmath].to_s}],
+ displayMath: [#{Asciidoctor::BLOCK_MATH_DELIMITERS[:latexmath].to_s}],
+ ignoreClass: "nostem|nolatexmath"
+ },
+ asciimath2jax: {
+ delimiters: [#{Asciidoctor::BLOCK_MATH_DELIMITERS[:asciimath].to_s}],
+ ignoreClass: "nostem|noasciimath"
+ },
+ TeX: {#{eqnums_opt}}
+ });
+ script src='#{cdn_base}/mathjax/2.4.0/MathJax.js?config=TeX-MML-AM_HTMLorMML'
+ - case attr 'source-highlighter'
+ - when 'coderay'
+ - if (attr 'coderay-css', 'class') == 'class'
+ - if @safe >= Asciidoctor::SafeMode::SECURE || (attr? :linkcss)
+ link rel='stylesheet' href=normalize_web_path('asciidoctor-coderay.css', (attr :stylesdir, ''))
+ - else
+ style=Asciidoctor::Stylesheets.instance.coderay_stylesheet_data
+ - when 'pygments'
+ - if (attr 'pygments-css', 'class') == 'class'
+ - if @safe >= Asciidoctor::SafeMode::SECURE || (attr? :linkcss)
+ link rel='stylesheet' href=normalize_web_path('asciidoctor-pygments.css', (attr :stylesdir, ''))
+ - else
+ style=Asciidoctor::Stylesheets.instance.pygments_stylesheet_data(attr 'pygments-style')
+ / For syntax highlighting
+ - if attr? 'highlightjs-theme'
+ link href=(attr 'highlightjs-theme') rel="stylesheet"
+ - else
+ link href="#{revealjsdir}/lib/css/zenburn.css" rel="stylesheet"
+ / If the query includes 'print-pdf', use the PDF print sheet
+ javascript:
+ var link = document.createElement( 'link' );
+ link.rel = 'stylesheet';
+ link.type = 'text/css';
+ link.href = window.location.search.match( /print-pdf/gi ) ? "#{revealjsdir}/css/print/pdf.css" : "#{revealjsdir}/css/print/paper.css";
+ document.getElementsByTagName( 'head' )[0].appendChild( link );
+ /[if lt IE 9]
+ <script src="#{revealjsdir}/lib/js/html5shiv.js"></script>
+ - unless (docinfo_content = docinfo :header, '.html').empty?
+ =docinfo_content
+ - if attr? :customcss
+ link rel='stylesheet' href=((customcss = attr :customcss).empty? ? 'asciidoctor-revealjs.css' : customcss)
+ body
+ .header
+ .left
+ .right
+ .reveal
+ / Any section element inside of this container is displayed as a slide
+ .slides
+ - unless notitle || !has_header?
+ - bg_image = (attr? 'title-slide-background-image') ? (image_uri(attr 'title-slide-background-image')) : nil
+ - bg_video = (attr? 'title-slide-background-video') ? (media_uri(attr 'title-slide-background-video')) : nil
+ section.title(class = role
+ data-state='title'
+ data-transition=(attr 'title-slide-transition')
+ data-transition-speed=(attr 'title-slide-transition-speed')
+ data-background=(attr 'title-slide-background')
+ data-background-size=(attr 'title-slide-background-size')
+ data-background-image=bg_image
+ data-background-video=bg_video
+ data-background-video-loop=(attr 'title-slide-background-video-loop')
+ data-background-video-muted=(attr 'title-slide-background-video-muted')
+ data-background-iframe=(attr 'title-slide-background-iframe')
+ data-background-color=(attr 'title-slide-background-color')
+ data-background-repeat=(attr 'title-slide-background-repeat')
+ data-background-position=(attr 'title-slide-background-position')
+ data-background-transition=(attr 'title-slide-background-transition'))
+ - if (_title_obj = doctitle partition: true, use_fallback: true).subtitle?
+ h1=slice_text _title_obj.title, (_slice = header.option? :slice)
+ h2=slice_text _title_obj.subtitle, _slice
+ - else
+ h1=@header.title
+ - preamble = @document.find_by context: :preamble
+ - unless preamble.nil? or preamble.length == 0
+ div.preamble=preamble.pop.content
+ - unless author.nil?
+ p.author: small=author
+ =content
+ .footer
+ .left
+ .right
+ script src="#{revealjsdir}/lib/js/head.min.js"
+ script src="#{revealjsdir}/js/reveal.js"
+ javascript:
+ // See https://github.com/hakimel/reveal.js#configuration for a full list of configuration options
+ Reveal.initialize({
+ // Display controls in the bottom right corner
+ controls: #{to_boolean(attr 'revealjs_controls', true)},
+ // Display a presentation progress bar
+ progress: #{to_boolean(attr 'revealjs_progress', true)},
+ // Set a per-slide timing for speaker notes, null means none
+ defaultTiming: #{attr 'revealjs_defaultTiming', 'null'},
+ // Display the page number of the current slide
+ slideNumber: #{to_boolean(attr 'revealjs_slidenumber', false)},
+ // Push each slide change to the browser history
+ history: #{to_boolean(attr 'revealjs_history', false)},
+ // Enable keyboard shortcuts for navigation
+ keyboard: #{to_boolean(attr 'revealjs_keyboard', true)},
+ // Enable the slide overview mode
+ overview: #{to_boolean(attr 'revealjs_overview', true)},
+ // Vertical centering of slides
+ center: #{to_boolean(attr 'revealjs_center', true)},
+ // Enables touch navigation on devices with touch input
+ touch: #{to_boolean(attr 'revealjs_touch', true)},
+ // Loop the presentation
+ loop: #{to_boolean(attr 'revealjs_loop', false)},
+ // Change the presentation direction to be RTL
+ rtl: #{to_boolean(attr 'revealjs_rtl', false)},
+ // Randomizes the order of slides each time the presentation loads
+ shuffle: #{to_boolean(attr 'revealjs_shuffle', false)},
+ // Turns fragments on and off globally
+ fragments: #{to_boolean(attr 'revealjs_fragments', true)},
+ // Flags if the presentation is running in an embedded mode,
+ // i.e. contained within a limited portion of the screen
+ embedded: #{to_boolean(attr 'revealjs_embedded', false)},
+ // Flags if we should show a help overlay when the questionmark
+ // key is pressed
+ help: #{to_boolean(attr 'revealjs_help', true)},
+ // Flags if speaker notes should be visible to all viewers
+ showNotes: #{to_boolean(attr 'revealjs_showNotes', false)},
+ // Global override for autolaying embedded media (video/audio/iframe)
+ // - null: Media will only autoplay if data-autoplay is present
+ // - true: All media will autoplay, regardless of individual setting
+ // - false: No media will autoplay, regardless of individual setting
+ autoPlayMedia: #{attr 'revealjs_autoPlayMedia', 'null'},
+ // Number of milliseconds between automatically proceeding to the
+ // next slide, disabled when set to 0, this value can be overwritten
+ // by using a data-autoslide attribute on your slides
+ autoSlide: #{attr 'revealjs_autoslide', 0},
+ // Stop auto-sliding after user input
+ autoSlideStoppable: #{to_boolean(attr 'revealjs_autoslidestoppable', true)},
+ // Enable slide navigation via mouse wheel
+ mouseWheel: #{to_boolean(attr 'revealjs_mousewheel', false)},
+ // Hides the address bar on mobile devices
+ hideAddressBar: #{to_boolean(attr 'revealjs_hideaddressbar', true)},
+ // Opens links in an iframe preview overlay
+ previewLinks: #{to_boolean(attr 'revealjs_previewlinks', false)},
+ // Theme (e.g., beige, black, league, night, serif, simple, sky, solarized, white)
+ // NOTE setting the theme in the config no longer works in reveal.js 3.x
+ //theme: Reveal.getQueryHash().theme || '#{attr 'revealjs_theme', 'black'}',
+ // Transition style (e.g., none, fade, slide, convex, concave, zoom)
+ transition: Reveal.getQueryHash().transition || '#{attr 'revealjs_transition', 'slide'}',
+ // Transition speed (e.g., default, fast, slow)
+ transitionSpeed: '#{attr 'revealjs_transitionspeed', 'default'}',
+ // Transition style for full page slide backgrounds (e.g., none, fade, slide, convex, concave, zoom)
+ backgroundTransition: '#{attr 'revealjs_backgroundtransition', 'fade'}',
+ // Number of slides away from the current that are visible
+ viewDistance: #{attr 'revealjs_viewdistance', 3},
+ // Parallax background image (e.g., "'https://s3.amazonaws.com/hakim-static/reveal-js/reveal-parallax-1.jpg'")
+ parallaxBackgroundImage: '#{attr 'revealjs_parallaxbackgroundimage', ''}',
+ // Parallax background size in CSS syntax (e.g., "2100px 900px")
+ parallaxBackgroundSize: '#{attr 'revealjs_parallaxbackgroundsize', ''}',
+
+ // The "normal" size of the presentation, aspect ratio will be preserved
+ // when the presentation is scaled to fit different resolutions. Can be
+ // specified using percentage units.
+ width: #{attr 'revealjs_width', 960},
+ height: #{attr 'revealjs_height', 700},
+
+ // Factor of the display size that should remain empty around the content
+ margin: #{attr 'revealjs_margin', 0.1},
+
+ // Bounds for smallest/largest possible scale to apply to content
+ minScale: #{attr 'revealjs_minscale', 0.2},
+ maxScale: #{attr 'revealjs_maxscale', 1.5},
+
+ // Optional libraries used to extend on reveal.js
+ dependencies: [
+ { src: '#{revealjsdir}/lib/js/classList.js', condition: function() { return !document.body.classList; } },
+ { src: '#{revealjsdir}/plugin/markdown/marked.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+ { src: '#{revealjsdir}/plugin/markdown/markdown.js', condition: function() { return !!document.querySelector( '[data-markdown]' ); } },
+ #{(attr? 'source-highlighter', 'highlightjs') ? "{ src: '#{revealjsdir}/plugin/highlight/highlight.js', async: true, callback: function() { hljs.initHighlightingOnLoad(); } }," : nil}
+ { src: '#{revealjsdir}/plugin/zoom-js/zoom.js', async: true },
+ { src: '#{revealjsdir}/plugin/notes/notes.js', async: true }
+ ]
+ });
+ - unless (docinfo_content = (docinfo :footer, '.html')).empty?
+ =docinfo_content
diff --git a/content/ZooKeeper/pom.xml b/content/ZooKeeper/pom.xml
new file mode 100644
index 0000000..bf94cca
--- /dev/null
+++ b/content/ZooKeeper/pom.xml
@@ -0,0 +1,289 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+ <modelVersion>4.0.0</modelVersion>
+
+ <parent>
+ <groupId>org.apache</groupId>
+ <artifactId>apache</artifactId>
+ <version>21</version>
+
+ <!-- Required in our case as per http://maven.apache.org/ref/3.0.3/maven-model/maven.html#class_parent -->
+ <relativePath></relativePath>
+ </parent>
+
+ <groupId>org.apache.training</groupId>
+ <artifactId>apache-zookeeper</artifactId>
+ <version>1.0.0-SNAPSHOT</version>
+ <packaging>war</packaging>
+
+ <name>Training: Apache ZooKeeper</name>
+
+ <properties>
+ <project.slides.directory>${project.build.directory}/generated-slides</project.slides.directory>
+ <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+
+ <asciidoctor.maven.plugin.version>2.0.0-RC.1</asciidoctor.maven.plugin.version>
+ <asciidoctorj.version>2.0.0-RC.2</asciidoctorj.version>
+ <asciidoctorj.diagram.version>1.5.16</asciidoctorj.diagram.version>
+ <asciidoctorj.extensions-lab.version>1.0.0</asciidoctorj.extensions-lab.version>
+ <revealjs.version>3.7.0</revealjs.version>
+ <asciidoctor-revealjs.version>2.0.0</asciidoctor-revealjs.version>
+
+ <download-maven-plugin.version>1.4.1</download-maven-plugin.version>
+ <maven-resources-plugin.version>3.1.0</maven-resources-plugin.version>
+ <maven-war-plugin.version>3.2.2</maven-war-plugin.version>
+ <jetty-maven-plugin.version>9.4.14.v20181114</jetty-maven-plugin.version>
+ </properties>
+
+ <build>
+ <plugins>
+ <!-- Check if all source files have the required apache license headers -->
+ <plugin>
+ <groupId>org.apache.rat</groupId>
+ <artifactId>apache-rat-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>license-check</id>
+ <phase>verify</phase>
+ <goals>
+ <goal>check</goal>
+ </goals>
+ </execution>
+ </executions>
+ <configuration>
+ <consoleOutput>true</consoleOutput>
+ <excludes>
+ <!-- TODO: This is a mofified version of an asciidoctor file ... nor sure we can stick an Apache Header on it -->
+ <exclude>libs/docinfo-hack/document.html.slim</exclude>
+ <!-- Exclude everything downloaded by the install-deps scripts -->
+ <exclude>libs/third-party/**</exclude>
+ <!-- Maven related files -->
+ <exclude>**/target/**</exclude>
+
+ <!-- Eclipse related files -->
+ <exclude>**/.project</exclude>
+ <exclude>**/.settings/**</exclude>
+ <exclude>**/.classpath</exclude>
+
+ <!-- IntelliJ related files -->
+ <exclude>**/.idea/**</exclude>
+ <exclude>**/*.iml</exclude>
+
+ <!-- Asciidoctor generated files -->
+ <exclude>**/.asciidoctor/**</exclude>
+
+ <!-- JSON doesn't like comments -->
+ <exclude>**/*.json</exclude>
+ <!-- Mermaid does't like comments -->
+ <exclude>**/*.mmd</exclude>
+
+ <!-- Output of the profiler maven extension -->
+ <exclude>**/.profiler/**</exclude>
+ </excludes>
+ </configuration>
+ </plugin>
+
+ <plugin>
+ <groupId>com.googlecode.maven-download-plugin</groupId>
+ <artifactId>download-maven-plugin</artifactId>
+ <version>${download-maven-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>install-asciidoctor-revealjs</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://github.com/asciidoctor/asciidoctor-reveal.js/archive/v${asciidoctor-revealjs.version}.zip</url>
+ <unpack>true</unpack>
+ <outputFileName>asciidoctor-reveal.js-${asciidoctor-revealjs.version}.zip</outputFileName>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>install-revealjs</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://github.com/hakimel/reveal.js/archive/${revealjs.version}.zip</url>
+ <unpack>true</unpack>
+ <outputFileName>reveal.js-${revealjs.version}.zip</outputFileName>
+ <outputDirectory>${project.slides.directory}</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>download-c3-css</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.12/c3.min.css</url>
+ <outputDirectory>${project.slides.directory}/css</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>download-c3-js</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://cdnjs.cloudflare.com/ajax/libs/c3/0.6.12/c3.min.js</url>
+ <outputDirectory>${project.slides.directory}/js</outputDirectory>
+ </configuration>
+ </execution>
+ <execution>
+ <id>download-d3-js</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>wget</goal>
+ </goals>
+ <configuration>
+ <url>https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js</url>
+ <outputDirectory>${project.slides.directory}/js</outputDirectory>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-resources-plugin</artifactId>
+ <version>${maven-resources-plugin.version}</version>
+ <executions>
+ <execution>
+ <id>copy-resources</id>
+ <phase>generate-resources</phase>
+ <goals>
+ <goal>copy-resources</goal>
+ </goals>
+ <configuration>
+ <outputDirectory>${project.build.directory}</outputDirectory>
+ <resources>
+ <!-- Copy the normal resources into the root of the slides directory -->
+ <resource>
+ <directory>src/main/resources</directory>
+ <targetPath>${project.slides.directory}</targetPath>
+ </resource>
+ <!-- Copy our css-theme to the reveal.js theme directory -->
+ <resource>
+ <directory>src/main/theme</directory>
+ <filtering>true</filtering>
+ <targetPath>${project.slides.directory}/reveal.js-${revealjs.version}/css/theme</targetPath>
+ </resource>
+ <!-- Patch one of the "slim" files as the 'docinfo' integration doesn't seem to work -->
+ <resource>
+ <directory>libs/docinfo-hack</directory>
+ <targetPath>${project.build.directory}/asciidoctor-reveal.js-${asciidoctor-revealjs.version}/templates</targetPath>
+ </resource>
+ </resources>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ <plugin>
+ <groupId>org.asciidoctor</groupId>
+ <artifactId>asciidoctor-maven-plugin</artifactId>
+ <version>${asciidoctor.maven.plugin.version}</version>
+ <executions>
+ <execution>
+ <id>generate-slides</id>
+ <phase>process-resources</phase>
+ <goals>
+ <goal>process-asciidoc</goal>
+ </goals>
+ <configuration>
+ <!-- Tell asciidoctor to use the reveal.js backend and not the default html -->
+ <backend>revealjs</backend>
+ <!-- Configure where are all the asciidoc source files located -->
+ <sourceDirectory>src/main/asciidoc</sourceDirectory>
+ <!-- Configure the target director to where will the output be generated -->
+ <outputDirectory>${project.slides.directory}</outputDirectory>
+ <!-- output file-->
+ <outputFile>index.html</outputFile>
+ <!-- Enable optional modules for generating diagrams and charts -->
+ <requires>
+ <require>asciidoctor-diagram</require>
+ <!--require>chart-block-macro</require-->
+ </requires>
+ <!-- This has to point to the asciidoctor-revealjs directory which contains all the "slim" files -->
+ <templateDir>${project.build.directory}/asciidoctor-reveal.js-${asciidoctor-revealjs.version}/templates</templateDir>
+ <sourceDocumentName>index_en.adoc</sourceDocumentName>
+ <attributes>
+ <!--imagesdir></imagesdir-->
+ <!--
+ Tell the system the relative path to the reveal.js files
+ inside the generated-slides directory.
+ -->
+ <revealjsdir>reveal.js-${revealjs.version}</revealjsdir>
+ <!--
+ Use our custom theme, which is defined by src/main/theme/apache.css
+ and copied inside the reveal.js installation by the resources plugin a few lines
+ up inside this pom.
+ -->
+ <revealjs_theme>apache</revealjs_theme>
+ <!-- Some basic settings -->
+ <revealjs_transition>linear</revealjs_transition>
+ <project-version>${project.version}</project-version>
+ <source-highlighter>highlightjs</source-highlighter>
+ <erd>${basedir}/libs/third-party/erd/.stack-work/dist/x86_64-osx/Cabal-2.2.0.1/build/erd/erd</erd>
+ <mermaid>${basedir}/libs/third-party/node_modules/.bin/mmdc</mermaid>
+ <phantomjs>${basedir}/libs/third-party/phantomjs-2.1.1-macosx/bin/phantomjs</phantomjs>
+ <svgbob>${basedir}/libs/third-party/svgbob/bin/svgbob</svgbob>
+ <vg2svg>${basedir}/libs/third-party/node_modules/.bin/vg2svg</vg2svg>
+ </attributes>
+ </configuration>
+ </execution>
+ </executions>
+ <dependencies>
+ <dependency>
+ <groupId>org.asciidoctor</groupId>
+ <artifactId>asciidoctorj</artifactId>
+ <version>${asciidoctorj.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.asciidoctor</groupId>
+ <artifactId>asciidoctorj-diagram</artifactId>
+ <version>${asciidoctorj.diagram.version}</version>
+ </dependency>
+ </dependencies>
+ </plugin>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-war-plugin</artifactId>
+ <version>${maven-war-plugin.version}</version>
+ <configuration>
+ <failOnMissingWebXml>false</failOnMissingWebXml>
+ <warSourceDirectory>${project.build.directory}/generated-slides</warSourceDirectory>
+ </configuration>
+ </plugin>
+ <plugin>
+ <groupId>org.eclipse.jetty</groupId>
+ <artifactId>jetty-maven-plugin</artifactId>
+ <version>${jetty-maven-plugin.version}</version>
+ </plugin>
+ </plugins>
+ </build>
+</project>
diff --git a/content/ZooKeeper/src/main/asciidoc/index_de.adoc b/content/ZooKeeper/src/main/asciidoc/index_de.adoc
new file mode 100644
index 0000000..39beaac
--- /dev/null
+++ b/content/ZooKeeper/src/main/asciidoc/index_de.adoc
@@ -0,0 +1,116 @@
+////
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+////
+
+
+[%notitle]
+== Apache ZooKeeper
+:description: Kurzeinführung in Apache ZooKeeper
+:keywords: Apache ZooKeeper
+
+image::http://www.apache.org/logos/res/zookeeper/zookeeper.png[]
+
+
+== Einführung
+
+ZooKeeper ist ein verteilter, hochverfügbarer, skalierbarer und strikt konsistenter data store
+
+
+== Einführung
+* Current version is 3.4.14 (April 2019)
+* Eine neue Version 3.5 ist in der Entwicklung (3.5.5-beta, aus dem Mai 2019)
+** Schon seit ca. 2014
+** Wichtige neue Features: Dynamic Reconfiguration, "container" znode
+* Eines der erste Tools aus dem Hadoop Ökosystem
+* Ursprünglich bei Yahoo! gebaut, nun ein Apache Projekt
+
+
+== Use Cases
+* Wird von vielen Tools aus dem Hadoop Ökosystem genutzt
+** HA (HBase, YARN, Hive, …)
+** Koordination (HBase, ...)
+* "Rezepte", die einfach mit ZooKeeper zu implementieren sind:
+** Group Membership, Name Service, Configuration, Barriers, Queues, Locks, Leader Election, Two-phased commit
+* Während ZooKeeper im Hadoop Ökosystem entstanden ist, wird es heute viel außerhalb genutzt
+** z.B. Solr und andere Tools
+
+
+== Data Model
+image::data-model.png[]
+
+
+== Data Model
+* Hierarchie von "nodes" (znode genannt)
+** Ähnlich wie in Dateisystemen
+* Jeder znode kann sowohl andere nodes als Kinder haben als auch Daten
+** Dies ist anders als in herkömmlichen Dateisystemen wo ein Knoten *entweder* eine Datei *oder* ein Verzeichnis ist
+** Die Daten in einem Knoten sind normalerweise klein
+** Im Bereich weniger Kilobyte
+
+
+== Data Model
+* Alle Updates sind streng sortiert und nur ein einzelner Master Prozess schreibt Daten, daher ist ZooKeeper nicht als data store für hohes Transaktionsvolumen ausgelegt
+* ZooKeeper kennt "ephemeral" Nodes welche automatisch gelöscht werden wenn die Session geschlossen wird in der sie erstellt wurden
+** Kann benutzt werden um verfügbare Server zu überwachen
+** Man kann ein "Watch" auf ein ZNode setzen und bekommt dann eine Benachrichtigung wenn sich einer ändert
+
+
+== Implementation Details
+* ZooKeeper benutzt ein wire protocol basierend auf einer Bibliothek namens "Jute"
+** Ursrprünglich aus Hadoop extrahiert
+** Nicht außerhalb von ZooKeeper verwendet
+* Es gibt native Clients für C und Java
+** Andere (z.b. Python) werden von der Community verwaltetOther (e.g. Python)
+* Apache Curator ist eine Java basierte Client Library, die häufig zum Zugriff verwendet wird da sie high level Konzepte in ihrer API anbietet
+
+
+== Zab Protocol
+* ZooKeeper kann mehrere Server verwenden, dies heißt dann ein "Ensemble"
+* ZooKeeper bentutz ein Protokoll/Algorithmus namens _Zab_ um zuverlässige Lieferungen und totale und kausale Reihenfolge von Nachrichten zu bieten trotz unzuverlässiger Netzwerke
+* In einem Ensemble gibt es höchstens einen Leader welcher unterstüttz wird von einer Mehrheit an Followern
+
+
+== Zab Protocol
+* Alle Server wählen einen Leader
+** Leader ist derjenige mit den meisten Stimmen (Quorum)
+** Daher meist eine ungerade Anzahl an Servern
+* Alle Servers können Read requests beantworten aber alle Schreibrequests werden an den Leader weitergeleitet
+** Clients können trotzdem mit einem beliebigen Server sprechen, die Requests werden automatisch weiter geleitete
+
+
+== Scaling
+* Alle Datenänderungen werden zur Wahl gestellt (koordiniert vom Leader)
+* Je mehr Server es gibt desto länger dauert dieser Prozess
+* Daher gibt es das Konzept von "participants"und "observern"
+** Participants wählen mit
+** Observer nehmen nicht aktiv an der Wahl teil sondern hören nur auf das Ergebnis
+* Das erlaubt es ZooKeeper einfach zu skalieren ohne auf Performanzeinbusse hinzunehmen
+
+
+== ZooKeeper 3.5 - Ausblick
+* Container nodes
+** Wenn all child nodes gelöscht wurden kann auch der container node automatisch gelöscht werden
+* TTL nodes
+** Wenn ein TTL node erstellt wird kann eine Time-to-Live (TTL) in ms angegeben werden
+** Wenn der Knoten innehalb der TTL nicht modifiziert wurde und er keine child nodes hat wird er automatisch gelöscht
+
+
+== ZooKeeper 3.5 - Ausblick
+* Dynamic Reconfiguration
+** Vor 3.5 waren die Mitgliedschafen in einem Ensemble statisch, ein Neustart war erforderlich um das zu ändern
+** Ab Version 3.5 kann dies (und viel mehr) dynamisch geändert werden ohne, dass ein Neustart erforderlich ist
diff --git a/content/ZooKeeper/src/main/asciidoc/index_en.adoc b/content/ZooKeeper/src/main/asciidoc/index_en.adoc
new file mode 100644
index 0000000..b9f82ef
--- /dev/null
+++ b/content/ZooKeeper/src/main/asciidoc/index_en.adoc
@@ -0,0 +1,116 @@
+////
+
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You under the Apache License, Version 2.0
+ (the "License"); you may not use this file except in compliance with
+ the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+////
+
+
+[%notitle
+== Apache ZooKeeper
+:description: Brief introduction to Apache ZooKeeper
+:keywords: Apache ZooKeeper
+
+image::http://www.apache.org/logos/res/zookeeper/zookeeper.png[]
+
+
+== Introduction
+
+ZooKeeper is a distributed, highly available, scalable and strictly consistent hierarchical data store
+
+
+== Introduction
+* Current version is 3.4.14 (April 2019)
+* A new version 3.5 is under development (3.5.5-beta, May 2019)
+** And has been since 2014 or so
+** Major new features: Dynamic Reconfiguration, "container" znode, more later
+* One of the first tools from the Hadoop ecosystem
+* Built at Yahoo!, now an Apache project
+
+
+== Use Cases
+* Foundation for many features in the Hadoop ecosystem
+** HA (HBase, YARN, Hive, …)
+** Coordination (HBase, ...)
+* "Recipes" easily implemented using ZooKeeper:
+** Group Membership, Name Service, Configuration, Barriers, Queues, Locks, Leader Election, Two-phased commit
+* While ZooKeeper originated within the Hadoop ecosystem it is used heavily outside of it as well
+** e.g. Solr and others
+
+
+== Data Model
+image::data-model.png[]
+
+
+== Data Model
+* Hierarchy of nodes (called znode)
+** Similar to typical file systems
+* Each node can "contain" other nodes as well as data
+** Different from file systems where a node is *either* a file *or* a directory
+* Data in a node is usually small
+** In the kilobyte range
+
+
+== Data Model
+* As all updates are strictly ordered and only a single master processes writes ZooKeeper is not meant as a high-volume data store
+* ZooKeeper knows "ephemeral" nodes which get deleted automatically once the session is closed in which it was created
+** Can be used to get notified of failed servers
+** ZNodes can be watched (i.e. notifications on changes)
+
+
+== Implementation Details
+* ZooKeeper uses a wire protocol based on a library called "Jute"
+** Extracted from Hadoop
+** Not used outside of ZooKeeper
+* There are native clients for C and Java
+** Other (e.g. Python) clients maintained by the community
+* Apache Curator is a Java based client library that is often easier to use than the native one as it offers higher level concepts
+
+
+== Zab Protocol
+* ZooKeeper can use multiple servers in what's called an "Ensemble"
+* ZooKeeper uses an algorithm called Zab to guarantee reliable delivery, total and causal order of messages in the face of unreliable networks
+* In an ensemble there is at most one leader server supported by a majority of followers
+
+
+== Zab Protocol
+* All servers elect a leader
+** Leader is the one with the most votes (i.e. majority or quorum)
+** For this reason usually an odd number of servers
+* All servers can serve read requests but all write requests are forwarded to the Leader
+** Clients can still talk to any server, they forward the requests appropriately
+
+
+== Scaling
+* All changes in the system are voted upon (coordinated by the Leader)
+* The more servers there are the longer this process takes
+* Hence the concept of "participants" and "observers" exists
+** Participant servers take part in votes
+** Observers are non-voting member which only hear the results of votes
+* This allows ZooKeeper to scale more easily without sacrificing performance
+
+
+== ZooKeeper 3.5 - Outlook
+* Container nodes
+** When all child nodes have been deleted the container node may also be deleted automatically at some point
+* TTL nodes
+** When creating a node a TTL (in ms) can be specified
+** When the node has not been modified within the TTL and there are no children it may also be deleted automatically
+
+
+== ZooKeeper 3.5 - Outlook
+* Dynamic Reconfiguration
+** Before 3.5 the membership of the ensemble and all configuration parameters were static, a restart was required to change this
+** Starting in 3.5 this (and more) can be changed dynamically without requiring restarts
diff --git a/content/ZooKeeper/src/main/resources/images/data-model.graffle b/content/ZooKeeper/src/main/resources/images/data-model.graffle
new file mode 100644
index 0000000..7ef7a2d
Binary files /dev/null and b/content/ZooKeeper/src/main/resources/images/data-model.graffle differ
diff --git a/content/ZooKeeper/src/main/resources/images/data-model.png b/content/ZooKeeper/src/main/resources/images/data-model.png
new file mode 100644
index 0000000..8a5073e
Binary files /dev/null and b/content/ZooKeeper/src/main/resources/images/data-model.png differ
diff --git a/content/ZooKeeper/src/main/theme/apache.css b/content/ZooKeeper/src/main/theme/apache.css
new file mode 100644
index 0000000..079a53f
--- /dev/null
+++ b/content/ZooKeeper/src/main/theme/apache.css
@@ -0,0 +1,349 @@
+/*
+ Licensed to the Apache Software Foundation (ASF) under one
+ or more contributor license agreements. See the NOTICE file
+ distributed with this work for additional information
+ regarding copyright ownership. The ASF licenses this file
+ to you under the Apache License, Version 2.0 (the
+ "License"); you may not use this file except in compliance
+ with the License. You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing,
+ software distributed under the License is distributed on an
+ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ KIND, either express or implied. See the License for the
+ specific language governing permissions and limitations
+ under the License.
+*/
+
+section.has-light-background, section.has-light-background h1, section.has-light-background h2, section.has-light-background h3, section.has-light-background h4, section.has-light-background h5, section.has-light-background h6 {
+ color: #fff; }
+
+/*********************************************
+ * GLOBAL STYLES
+ *********************************************/
+body {
+ background-image: url("../../../images/background.jpg");
+ background-repeat: no-repeat;
+ background-size: cover;
+ background-color: #fff; }
+
+.reveal {
+ font-family: Panton-Regular, Helvetica, sans-serif;
+ font-size: 34px;
+ font-weight: normal;
+ color: #000; }
+
+::selection {
+ color: #000;
+ background: #bee4fd;
+ text-shadow: none; }
+
+.reveal .slides > section, .reveal .slides > section > section {
+ line-height: 1.3;
+ font-weight: inherit; }
+
+/*********************************************
+ * HEADERS
+ *********************************************/
+.reveal h1, .reveal h2, .reveal h3, .reveal h4, .reveal h5, .reveal h6 {
+ margin: 0 0 20px 0;
+ color: #000;
+ font-family: Panton-Regular, Helvetica, sans-serif;
+ font-weight: 600;
+ line-height: 1.2;
+ letter-spacing: normal;
+ text-transform: uppercase;
+ text-shadow: none;
+ word-wrap: break-word; }
+
+.reveal h1 {
+ font-size: 2.5em; }
+
+.reveal h2 {
+ font-size: 1.6em; }
+
+.reveal h3 {
+ font-size: 1.3em; }
+
+.reveal h4 {
+ font-size: 1em; }
+
+.reveal h1 {
+ text-shadow: none; }
+
+/*********************************************
+ * OTHER
+ *********************************************/
+.reveal p {
+ margin: 20px 0;
+ line-height: 1.3; }
+
+/* Ensure certain elements are never larger than the slide itself */
+.reveal img, .reveal video, .reveal iframe {
+ max-width: 95%;
+ max-height: 95%; }
+
+.reveal strong, .reveal b {
+ font-weight: bold; }
+
+.reveal em {
+ font-style: italic; }
+
+.reveal ol, .reveal dl, .reveal ul {
+ display: inline-block;
+ text-align: left;
+ margin: 0 0 0 1em; }
+
+.reveal ol {
+ list-style-type: decimal; }
+
+.reveal ul {
+ list-style-type: disc; }
+
+.reveal ul ul {
+ list-style-type: square; }
+
+.reveal ul ul ul {
+ list-style-type: circle; }
+
+.reveal ul ul, .reveal ul ol, .reveal ol ol, .reveal ol ul {
+ display: block;
+ margin-left: 40px; }
+
+.reveal dt {
+ font-weight: bold; }
+
+.reveal dd {
+ margin-left: 40px; }
+
+.reveal q, .reveal blockquote {
+ quotes: none; }
+
+.reveal blockquote {
+ display: block;
+ position: relative;
+ width: 70%;
+ margin: 20px auto;
+ padding: 5px;
+ font-style: italic;
+ background: rgba(255, 255, 255, 0.05);
+ box-shadow: 0 0 2px rgba(0, 0, 0, 0.2); }
+
+.reveal blockquote p:first-child, .reveal blockquote p:last-child {
+ display: inline-block; }
+
+.reveal q {
+ font-style: italic; }
+
+.reveal pre {
+ display: block;
+ position: relative;
+ width: 90%;
+ margin: 20px auto;
+ text-align: left;
+ font-size: 0.55em;
+ font-family: monospace;
+ line-height: 1.2em;
+ word-wrap: break-word;
+ box-shadow: 0 0 6px rgba(0, 0, 0, 0.3); }
+
+.reveal code {
+ font-family: monospace; }
+
+.reveal pre code {
+ display: block;
+ padding: 5px;
+ overflow: auto;
+ max-height: 400px;
+ word-wrap: normal;
+ background: #3F3F3F;
+ color: #DCDCDC; }
+
+.reveal table {
+ margin: auto;
+ border-collapse: collapse;
+ border-spacing: 0; }
+
+.reveal table th {
+ font-weight: bold; }
+
+.reveal table th, .reveal table td {
+ text-align: left;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ border-bottom: 1px solid; }
+
+.reveal table th[align="center"], .reveal table td[align="center"] {
+ text-align: center; }
+
+.reveal table th[align="right"], .reveal table td[align="right"] {
+ text-align: right; }
+
+.reveal table tr:last-child td {
+ border-bottom: none; }
+
+.reveal sup {
+ vertical-align: super; }
+
+.reveal sub {
+ vertical-align: sub; }
+
+.reveal small {
+ display: inline-block;
+ font-size: 0.6em;
+ line-height: 1.2em;
+ vertical-align: top; }
+
+.reveal small * {
+ vertical-align: top; }
+
+/*********************************************
+ * LINKS
+ *********************************************/
+.reveal a {
+ color: #42affa;
+ text-decoration: none;
+ -webkit-transition: color 0.15s ease;
+ -moz-transition: color 0.15s ease;
+ transition: color 0.15s ease; }
+
+.reveal a:hover {
+ color: #8dcffc;
+ text-shadow: none;
+ border: none; }
+
+.reveal .roll span:after {
+ color: #fff;
+ background: #068ee9; }
+
+/*********************************************
+ * IMAGES
+ *********************************************/
+.reveal section img {
+ margin: 15px 0;
+ /*background: rgba(255, 255, 255, 0.12);*/
+ /*border: 4px solid #fff;*/
+ /*box-shadow: 0 0 10px rgba(0, 0, 0, 0.15);*/ }
+
+.reveal a img {
+ -webkit-transition: all 0.15s linear;
+ -moz-transition: all 0.15s linear;
+ transition: all 0.15s linear; }
+
+.reveal a:hover img {
+ background: rgba(255, 255, 255, 0.2);
+ border-color: #42affa;
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.55); }
+
+/*********************************************
+ * NAVIGATION CONTROLS
+ *********************************************/
+.reveal .controls div.navigate-left, .reveal .controls div.navigate-left.enabled {
+ border-right-color: #42affa; }
+
+.reveal .controls div.navigate-right, .reveal .controls div.navigate-right.enabled {
+ border-left-color: #42affa; }
+
+.reveal .controls div.navigate-up, .reveal .controls div.navigate-up.enabled {
+ border-bottom-color: #42affa; }
+
+.reveal .controls div.navigate-down, .reveal .controls div.navigate-down.enabled {
+ border-top-color: #42affa; }
+
+.reveal .controls div.navigate-left.enabled:hover {
+ border-right-color: #8dcffc; }
+
+.reveal .controls div.navigate-right.enabled:hover {
+ border-left-color: #8dcffc; }
+
+.reveal .controls div.navigate-up.enabled:hover {
+ border-bottom-color: #8dcffc; }
+
+.reveal .controls div.navigate-down.enabled:hover {
+ border-top-color: #8dcffc; }
+
+/*********************************************
+ * PROGRESS BAR
+ *********************************************/
+.reveal .progress {
+ background: rgba(0, 0, 0, 0.2); }
+
+.reveal .progress span {
+ background: #42affa;
+ -webkit-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+ -moz-transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985);
+ transition: width 800ms cubic-bezier(0.26, 0.86, 0.44, 0.985); }
+
+/*********************************************
+ * SLIDE NUMBER
+ *********************************************/
+.reveal .slide-number {
+ color: #42affa; }
+
+.reveal .red {
+ color: red;
+}
+
+/*********************************************
+ * C3JS Charts
+ *********************************************/
+
+.c3 {
+ fill: white; }
+
+.c3 line, .c3 path {
+ stroke: white !important; }
+
+/*********************************************
+ * Custom styling of individual charts
+ *********************************************/
+
+#most-significant-barriers .c3-shape .c3-shape-2 .c3-bar .c3-bar-2 {
+ color: red;
+}
+
+/*********************************************
+ * Footer and Header
+ *********************************************/
+
+.header {
+ position:relative;
+}
+/*.header .left {
+ position:absolute;
+ top: 5px;
+ left: 5px;
+ width: 196px;
+ height: 100px;
+ background-image: url("../../../images/logo-building-iot.png");
+}*/
+.header .right {
+ position:absolute;
+ top: 5px;
+ right: 5px;
+ width: 246px;
+ height: 100px;
+ background-image: url("../../../images/logo-apache.png");
+}
+
+.footer {
+ position:relative;
+}
+/*.footer .left {
+ position:absolute;
+ bottom: 5px;
+ left: 5px;
+ width: 392px;
+ height: 50px;
+ background-image: url("../../../images/logo-company.png");
+}
+.footer .right {
+ position:absolute;
+ bottom: 5px;
+ right: 5px;
+ width: 306px;
+ height: 100px;
+ background-image: url("../../../images/logo-training.png");
+}*/
+