[guadec-web/oscp-2019] Merge content from master



commit ee418e5faca64d188e885daa932bd6ec11572f34
Author: Tom Tryfonidis <tomtryf gmail com>
Date:   Fri Sep 28 18:29:53 2018 +0300

    Merge content from master

 Gruntfile.js                                       |   156 +
 LICENSE.md                                         |    29 +
 README.md                                          |    97 +
 content/pages/about-the-city.md                    |    55 +
 content/pages/accommodation-others.md              |   139 +
 content/pages/accommodation.md                     |   134 +
 content/pages/code-of-conduct.md                   |   134 +
 content/pages/contact.md                           |     8 +
 content/pages/how-to-sponsor.html                  |    69 +
 content/pages/legal.md                             |     6 +
 content/pages/map.md                               |   210 +
 content/pages/materials.md                         |    37 +
 content/pages/photo-policy.md                      |    50 +
 content/pages/schedule.md                          |   123 +
 content/pages/social-events.md                     |   149 +
 content/pages/sponsors.md                          |    51 +
 content/pages/submit-a-proposal.md                 |    59 +
 content/pages/talks-and-events.md                  |    18 +
 content/pages/test-map.md                          |    37 +
 content/pages/tourism.md                           |   132 +
 content/pages/travel.md                            |   150 +
 content/pages/unconference.md                      |     6 +
 content/pages/venue.md                             |   191 +
 content/pages/videos.md                            |    13 +
 content/pages/visa.md                              |   120 +
 devel.sh                                           |    49 +
 guadec-web.doap                                    |    36 +
 package.json                                       |    15 +
 pelicanconf.py                                     |   160 +
 publishconf.py                                     |    46 +
 requirements.txt                                   |    13 +
 src/fonts/SourceSansPro-Regular.otf                |   Bin 0 -> 229588 bytes
 src/fonts/cantarell-bold.woff                      |   Bin 0 -> 27096 bytes
 src/fonts/cantarell-bold.woff2                     |   Bin 0 -> 21244 bytes
 src/fonts/open-iconic.eot                          |   Bin 0 -> 28196 bytes
 src/fonts/open-iconic.otf                          |   Bin 0 -> 20996 bytes
 src/fonts/open-iconic.svg                          |   543 +
 src/fonts/open-iconic.ttf                          |   Bin 0 -> 28028 bytes
 src/fonts/open-iconic.woff                         |   Bin 0 -> 14984 bytes
 src/graphics/socials.svg                           |     0
 src/haml/archives.haml                             |    38 +
 src/haml/article.haml                              |    79 +
 src/haml/author.haml                               |    30 +
 src/haml/authors.haml                              |    39 +
 src/haml/base/base.haml                            |   110 +
 src/haml/base/blog.haml                            |    36 +
 src/haml/categories.haml                           |    43 +
 src/haml/category.haml                             |    28 +
 src/haml/includes/cookiesmessage.haml              |    31 +
 src/haml/includes/feeds_head.haml                  |    43 +
 src/haml/includes/footlinks.haml                   |    47 +
 src/haml/includes/navbar.haml                      |    44 +
 src/haml/includes/pagination.haml                  |    33 +
 src/haml/includes/postlist_article.haml            |    46 +
 src/haml/includes/socials.haml                     |    24 +
 src/haml/includes/socialshare.haml                 |    25 +
 src/haml/includes/translations.haml                |    26 +
 src/haml/index.haml                                |   136 +
 src/haml/page.haml                                 |    41 +
 src/haml/period_archives.haml                      |    46 +
 src/haml/tag.haml                                  |    32 +
 src/haml/tags.haml                                 |    44 +
 src/img/Gnomelogo-footprint.png                    |   Bin 0 -> 5840 bytes
 src/img/Gnomelogo-footprint.svg                    |    63 +
 src/img/black_pixel.png                            |   Bin 0 -> 170 bytes
 src/img/gnome-logo.svg                             |   155 +
 src/img/icon-180x180.png                           |   Bin 0 -> 11124 bytes
 src/img/icon-192x192.png                           |   Bin 0 -> 12020 bytes
 src/img/icon-270x270.png                           |   Bin 0 -> 16567 bytes
 src/img/icon-32x32.png                             |   Bin 0 -> 1433 bytes
 src/img/skyline.png                                |   Bin 0 -> 409423 bytes
 src/img/social/facebook-sw.png                     |   Bin 0 -> 277 bytes
 src/img/social/googleplus-sw.png                   |   Bin 0 -> 514 bytes
 src/img/social/instagram-lw.png                    |   Bin 0 -> 1114 bytes
 src/img/social/instagram-mw.png                    |   Bin 0 -> 839 bytes
 src/img/social/instagram-sw.png                    |   Bin 0 -> 644 bytes
 src/img/social/instagram-xlw.png                   |   Bin 0 -> 1511 bytes
 src/img/social/mail-lw.png                         |   Bin 0 -> 796 bytes
 src/img/social/mail-mw.png                         |   Bin 0 -> 668 bytes
 src/img/social/mail-sw.png                         |   Bin 0 -> 480 bytes
 src/img/social/mail-xlw.png                        |   Bin 0 -> 1200 bytes
 src/img/social/pinterest-lw.png                    |   Bin 0 -> 1001 bytes
 src/img/social/pinterest-mw.png                    |   Bin 0 -> 828 bytes
 src/img/social/pinterest-sw.png                    |   Bin 0 -> 554 bytes
 src/img/social/pinterest-xlw.png                   |   Bin 0 -> 1619 bytes
 src/img/social/qrcode-sw.png                       |   Bin 0 -> 453 bytes
 src/img/social/rss-sw.png                          |   Bin 0 -> 566 bytes
 src/img/social/telegram-lw.png                     |   Bin 0 -> 878 bytes
 src/img/social/telegram-mw.png                     |   Bin 0 -> 749 bytes
 src/img/social/telegram-sw.png                     |   Bin 0 -> 535 bytes
 src/img/social/telegram-xlw.png                    |   Bin 0 -> 1472 bytes
 src/img/social/twitter-sw.png                      |   Bin 0 -> 472 bytes
 src/img/social/whatsapp-lw.png                     |   Bin 0 -> 1339 bytes
 src/img/social/whatsapp-mw.png                     |   Bin 0 -> 875 bytes
 src/img/social/whatsapp-sw.png                     |   Bin 0 -> 621 bytes
 src/img/social/whatsapp-xlw.png                    |   Bin 0 -> 2203 bytes
 src/img/social/youtube-lw.png                      |   Bin 0 -> 669 bytes
 src/img/social/youtube-mw.png                      |   Bin 0 -> 631 bytes
 src/img/social/youtube-sw.png                      |   Bin 0 -> 394 bytes
 src/img/social/youtube-xlw.png                     |   Bin 0 -> 1122 bytes
 src/img/transparent_pixel.png                      |   Bin 0 -> 168 bytes
 src/img/website/empty.png                          |   Bin 0 -> 168 bytes
 src/img/white_pixel.png                            |   Bin 0 -> 169 bytes
 src/js/01-jquery-3.2.1.js                          | 10253 +++++++++++++++++++
 src/js/02-popper-1.13.3.js                         |  2448 +++++
 src/js/03-bootstrap-4.0.0-beta.2.js                |  3850 +++++++
 src/js/guadec_map/.gitignore                       |     2 +
 src/js/guadec_map/guadec-map.js                    |   548 +
 src/js/guadec_map/maki-guadec-svg/airport-45.svg   |    49 +
 src/js/guadec_map/maki-guadec-svg/bank-45.svg      |    48 +
 src/js/guadec_map/maki-guadec-svg/bar-45.svg       |    52 +
 src/js/guadec_map/maki-guadec-svg/bus-45.svg       |    48 +
 src/js/guadec_map/maki-guadec-svg/cafe-45.svg      |    51 +
 src/js/guadec_map/maki-guadec-svg/circle-11.svg    |     7 +
 src/js/guadec_map/maki-guadec-svg/circle-45.svg    |    51 +
 .../maki-guadec-svg/gnome-guadec-blue.svg          |    72 +
 .../maki-guadec-svg/gnome-guadec-red.svg           |    72 +
 .../maki-guadec-svg/gnome-guadec-yellow.svg        |    72 +
 src/js/guadec_map/maki-guadec-svg/home-45.svg      |    51 +
 src/js/guadec_map/maki-guadec-svg/hospital-45.svg  |    51 +
 src/js/guadec_map/maki-guadec-svg/karaoke-45.svg   |    55 +
 src/js/guadec_map/maki-guadec-svg/lodging-45.svg   |    48 +
 src/js/guadec_map/maki-guadec-svg/marker-45.svg    |    48 +
 src/js/guadec_map/maki-guadec-svg/music-45.svg     |    51 +
 src/js/guadec_map/maki-guadec-svg/park-45.svg      |    51 +
 src/js/guadec_map/maki-guadec-svg/parking-45.svg   |    51 +
 src/js/guadec_map/maki-guadec-svg/rail-45.svg      |    51 +
 .../guadec_map/maki-guadec-svg/restaurant-45.svg   |    51 +
 src/js/guadec_map/maki-guadec-svg/rocket-45.svg    |    51 +
 src/js/guadec_map/maki-guadec-svg/star-11.svg      |    10 +
 src/js/guadec_map/maki-guadec-svg/star-45.svg      |    52 +
 src/js/guadec_map/maki-guadec-svg/suitcase-45.svg  |    49 +
 src/js/guadec_map/maki-guadec-svg/theatre-45.svg   |    51 +
 src/js/guadec_map/maki-guadec-svg/town-hall-45.svg |    51 +
 src/js/guadec_map/maki-guadec-svg/village-45.svg   |    48 +
 src/js/guadec_map/sprite.json                      |   191 +
 src/js/guadec_map/sprite.png                       |   Bin 0 -> 16588 bytes
 src/js/guadec_map/sprite 2x json                   |   191 +
 src/js/guadec_map/sprite 2x png                    |   Bin 0 -> 37353 bytes
 src/js/main.js                                     |   181 +
 src/sass/compass-sass-base/_animations.sass        |   196 +
 src/sass/compass-sass-base/_base.sass              |   143 +
 src/sass/compass-sass-base/_bootstrap.scss         |  8374 +++++++++++++++
 .../compass-sass-base/_open_iconic_bootstrap.scss  |   957 ++
 src/sass/compass-sass-base/_social.sass            |   160 +
 src/sass/noscript.sass                             |     2 +
 src/sass/screen.sass                               |   369 +
 147 files changed, 33481 insertions(+)
---
diff --git a/Gruntfile.js b/Gruntfile.js
new file mode 100644
index 0000000..a41d788
--- /dev/null
+++ b/Gruntfile.js
@@ -0,0 +1,156 @@
+/*
+Grunt tasks
+
+Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+module.exports = function (grunt) {
+
+    // Tasks configuration
+    grunt.initConfig({
+        pkg: grunt.file.readJSON('package.json'),
+
+        compass: {
+            dist: {
+                options: {
+                    sassDir: 'src/sass',
+                    cssDir: 'themes/<%= pkg.name %>/static/css',
+                    imagesDir: 'src/img',
+                    generatedImagesDir: 'themes/<%= pkg.name %>/static/img',
+                    httpGeneratedImagesPath: '../img',
+                    javascriptsDir: 'themes/<%= pkg.name %>/static/js',
+                    outputStyle: 'compressed',
+                    noLineComments: true,
+                    trace: true,
+                    environment: 'production'
+                }
+            }
+        },
+
+        concat: {
+            options: {
+                separator: ';',
+                process: false
+            },
+            dist: {
+                src: ['src/js/*.js'],
+                dest: 'themes/<%= pkg.name %>/static/js/scripts.js'
+            }
+        },
+
+        uglify: {
+            options: {
+                banner: '/*! <%= pkg.name %> <%= grunt.template.today("yyyymmddhhmmss") %> */\n'
+            },
+            dist: {
+                files: {
+                    '<%= concat.dist.dest %>': ['<%= concat.dist.dest %>']
+                }
+            }
+        },
+
+        jslint: {
+            frontend: {
+                src: [
+                    'src/js/*.js'
+                ],
+                exclude: [
+                ],
+                directives: {
+                    browser: true,
+                    unparam: true,
+                    todo: true,
+                    predef: [
+                        'jQuery',
+                        '$',
+                        'console'
+                    ]
+                },
+                options: {
+                    errorsOnly: true,
+                    failOnError: false,
+                    shebang: true,
+                    tabSize: 2
+                }
+            }
+        },
+
+        copy: {
+            images: {
+                files: [
+                    {
+                        expand: true,
+                        cwd: 'src/img/',
+                        src: ['**/*.{png,jpg,svg}'],
+                        dest: 'themes/<%= pkg.name %>/static/img/'
+                    }
+                ]
+            },
+            fonts: {
+                files: [
+                    {
+                        expand: true,
+                        cwd: 'src/fonts/',
+                        src: ['**/*'],
+                        dest: 'themes/<%= pkg.name %>/static/fonts/'
+                    }
+                ]
+            },
+            guadec_map: {
+                files: [
+                    {
+                        expand: true,
+                        cwd: 'src/js/guadec_map/',
+                        src: ['guadec-map.js','guadec-map-style.json','sprite*'],
+                        dest: 'themes/<%= pkg.name %>/static/js/guadec-map/'
+                    }
+                ]
+            }
+        },
+
+        watch: {
+            stylesheets: {
+                files: ['src/sass/**/*.scss', 'src/sass/**/*.sass', 'src/img/**/*'],
+                tasks: ['compass'],
+            },
+            scripts: {
+                files: ['src/js/**/*.js'],
+                tasks: ['jslint', 'concat','uglify','copy'],
+            },
+            images: {
+                files: ['src/img/**/*'],
+                tasks: ['copy']
+            }
+        }
+    });
+
+    // Plugin load
+    grunt.loadNpmTasks('grunt-contrib-concat');
+    grunt.loadNpmTasks('grunt-contrib-uglify');
+    grunt.loadNpmTasks('grunt-contrib-compass');
+    grunt.loadNpmTasks('grunt-jslint');
+    grunt.loadNpmTasks('grunt-contrib-watch');
+    grunt.loadNpmTasks('grunt-contrib-copy');
+
+    // Tasks
+    grunt.registerTask('devel', ['watch']);
+    grunt.registerTask('default', ['compass', 'concat', 'uglify', 'copy']);
+};
diff --git a/LICENSE.md b/LICENSE.md
new file mode 100644
index 0000000..d1afc62
--- /dev/null
+++ b/LICENSE.md
@@ -0,0 +1,29 @@
+Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+Third party components included partially included:
+
+Bootstrap - MIT License - https://github.com/twbs/bootstrap/blob/v4-dev/LICENSE
+
+Open Iconic: MIT License, Open Font License - https://www.useiconic.com/open
+
+jQuery: MIT License - https://jquery.org/license/
+
+Popper: MIT License - https://github.com/FezVrasta/popper.js/blob/master/LICENSE.md
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..20a51da
--- /dev/null
+++ b/README.md
@@ -0,0 +1,97 @@
+## GUADEC pelican website generator
+test
+This is a static website generator based on Pelican
+
+### Editing workflow for markdown files
+
+For editing content and pages, the steps are the following:
+
+1. Go to GUADEC web repo at https://gitlab.gnome.org/Infrastructure/guadec-web/
+2. Push the fork button and if asked, select your gitlab user
+3. The gitlab system will redirect you to your personal fork of the website repo
+4. Edit whatever markdown (.md) files you want to edit at content or content/pages
+5. Commit the changes in your personal copy
+6. Go to Merge Requests in gitlab left panel
+7. Create a new merge request using your personal repo and the master branch as source, and the 
infrastructure/guadec-web, master branch as target branch
+8. Press Compare branches and continue
+9. Fill the form specifying some information about the changes you have done, so they can be reviewed by 
someone in the repo acces list and then merge your changes into the website.
+
+### Writing content
+
+Under the content folder you can add content for the website. Articles and pages are written in 
[Markdown](https://daringfireball.net/projects/markdown/syntax).
+
+For more information about writing content for pelican, you can have a look at this 
[documentation](http://docs.getpelican.com/en/stable/content.html).
+
+#### Articles
+
+To add an article, just add a new markdown file under **content** directory. The file should at least have 
the following information:
+
+    Title: Article title
+    Date: 20180219
+    Category: News
+
+    Text for the article here
+
+Article date must be in the format YYYYMMDD HH:MM:SS and the time is optional
+
+There is also other metadata you can include in the article file:
+
+* Author: The author of this article
+* License: License information that will be displayed for this particular article
+* Description: Description that will be used in HTML meta description
+* Tags: List of tags for this article
+* Keywords: List of keywords that will be used in HTML meta keywords
+
+#### Pages
+
+The pages works the same way the articles do. The difference is that pages are not shown in any category and 
they live at **content/pages** directory.
+
+If you need to create a new page, make sure you link it from another page or in the menu (see configuration 
options below).
+
+#### Images and downloadable content
+
+The images are placed ad **content/images** directory and can be included into documents by using:
+
+    ![ALT Text]({filename}/images/image-name.jpg "Image title")
+
+### Advanced editing
+
+If you are an experienced user or want to edit the theming, you should clone the repo and prepare the 
development setup that follows.
+
+#### Dependencies
+
+For using this website generator you need to have in your system a working python install with pip, compass 
ruby gem and node.js. They are usually available in any distro.
+
+#### Initial setup
+
+The only thing you need to start is to execute
+
+    ./devel.sh
+
+This will install all the python packages you need into a virtual environment
+and the node packages needed for grunt tasks to run.
+
+Once the command finishes the execution you will have a development webserver running at
+
+    http://localhost:8000
+
+And every time you change content files or theme files they will be automatically regenerated to allow you 
to preview the changes you have done.
+
+### Theme
+
+All theme files lives at **src** directory. The template files are written in HAML, and CSS is written using 
SASS. You will usually not need to modify the theme.
+
+### Configuration options
+
+There are some customizations made for GUADEC website. The way to use them is to edit the **pelicanconf.py** 
file.
+
+It contains some variables with a very clear structure that can be customized for different purproses:
+
+* **GUADEC_LOACATION**: Name of the location displayed at index page header
+* **GUADEC_DATES**: Dates displayed at index page header
+* **MENU**: Structure for the top menu
+* **LINKS**: Links shown in the first column of the foot links
+* **GUADEC_LINKS**: Links shown in the second column of the foot links
+* **SOCIAL**: Social URLs to show at index page and at page foot.
+* **SPONSORS**: List of sponsors that will be shown at index page
+* **OPEN_REGISTRATION**: If True, enables registration links. Otherwise they are disabled.
diff --git a/content/pages/about-the-city.md b/content/pages/about-the-city.md
new file mode 100644
index 0000000..f588f5a
--- /dev/null
+++ b/content/pages/about-the-city.md
@@ -0,0 +1,55 @@
+Title: About Almería
+Date: 20180525
+
+
+![Tabernas 
desert](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c6/TabernasDesert.jpg/800px-TabernasDesert.jpg){:width="100%"}
+
+
+![Puerta 
Puchena](https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Puerta_Purchena._Almer%C3%ADa.jpg/320px-Puerta_Purchena._Almer%C3%ADa.jpg){:width="300px"
 align="right"}
+
+
+[Almería](https://en.wikipedia.org/wiki/Almer%C3%ADa) is a sunny, lovely city on the Southeast coast of 
Spain. On the shores of the Mediterranean sea, the city was founded in 955 by Abd-ar-Rahman III, who ordered 
the construction of the famous [Alcazaba (the 
Citadel)](https://en.wikipedia.org/wiki/Alcazaba_of_Almer%C3%ADa), one of the largest moorish castles in 
Europe. The modern city has grown over the hills that surround the Alcazaba, staying true to its visual and 
architectural tradition.
+
+
+Almería is also the administrative capital of the homonymous province and part of the [Autonomous Community 
of Andalusia](https://en.wikipedia.org/wiki/Andalusia). The region is famous for its prolific production of 
vegetables, having [over 100,000 acres of greenhouses in the Poniente 
province](https://en.wikipedia.org/wiki/Poniente_Almeriense#/media/File:Plastic_sea,_Almer%C3%ADa_Spain.jpg). 
Almería also hosts scientific research facilities like the [Calar Alto Astronomy 
Observatory](http://www.caha.es/), the [Almería Solar 
Platform](https://en.wikipedia.org/wiki/Plataforma_Solar_de_Almer%C3%ADa) and the [Experimental Station of 
Arid Zones](http://www.eeza.csic.es/en/).
+
+
+![Guitar 
Museum](https://upload.wikimedia.org/wikipedia/commons/thumb/a/ab/Museo_de_La_Guitarra._Almeria.jpg/320px-Museo_de_La_Guitarra._Almeria.jpg){:width="300px"
 align="right"}
+
+
+The city has about 195,000 inhabitants who are welcoming to visitors and always happy to enjoy the city's 
excellent weather with a vibrant day and night life. Some famous Almerians are Nicolás Salmerón y Alonso, the 
third president of the first Spanish Republic; as [Antonio de 
Torres](https://en.wikipedia.org/wiki/Antonio_de_Torres_Jurado), considered the father of the modern Spanish 
guitar; Fidela Campiña, a versatile opera singer; Carmen Pinteño, one of the best Almerian painters; more 
recently, José Fernández Torres “Tomatito”, one of the best flamenco guitarists in the world; and David 
Bisbal, the famous pop singer.
+
+
+Almería is also famous for its [popularity with the filmmaking 
industry](https://www.turismodealmeria.org/wp-content/uploads/2016/04/land-of-film.pdf). A good number of 
world famous films have been shot in the incomparable and varied landscapes and towns of the province. Since 
the sixties, Almería has attracted an enormous amount of films, commercial video and videoclips. Recent films 
like Exodus and TV series like Game of Thrones or Penny Dreadful have filmed here.
+
+
+![Almedina Street, Almería historical 
center](https://upload.wikimedia.org/wikipedia/commons/thumb/8/81/Calle_Almedina._Casco_antiguo_Almer%C3%ADa.jpg/309px-Calle_Almedina._Casco_antiguo_Almer%C3%ADa.jpg){:width="300px"
 align="right"}
+
+
+[Aldous Huxley visited Almería in 1929](http://www.almediam.org/PDF/Huxley.pdf). He was so taken by Almería 
that he wrote a sonnet about it:
+
+
+> Winds have no moving emblems here, bud scour<br>
+> A vacant darkness, un untempered ligth;<br>
+> No branches bend, never a tortured flower<br>
+> Shudders, root-weary, on the verge of fligth;<br>
+> Winged future, withered past, no seeds nor leaves<br>
+> Attest those swift invisible feet: they run<br>
+> Free through a naked land, whose breast recived<br>
+> All the fierce ardour of a naked sun.
+>
+> You have the Ligth for lover. Fortunate Earth!<br>
+> Conceive the fruit of his divine desire.<br>
+> But the dry dust is all she brings to birth,<br>
+> That child of clay by even celestial fire.<br>
+> Then come, soft rain and tender clouds, abate<br>
+> This shining love that has the force of hate.
+
+
+Visiting Almería is a great opportunity to [enjoy some 
tourism](https://wiki.gnome.org/IsmaelOlea/GUADEC-2018-Almeria-Bid-Toursm) with different landscapes and 
weathers, all less than 100 km away from the city.
+
+And if you believe being at the South of Spain can be very hot... well, maybe it is, but probably not as 
much you expect. Other cities in Andalucía, far from the sea, can be really hot in summer  with 40 ºC or more 
and hot enough. But being at the seaside our temperatures are always smoothed by the Mediterranean sea. Its 
weather is similar to places like Málaga, Barcelona, Alicante or Mallorca, which receive millions of tourists 
each year.
+
+Give yourself an opportunity to fall in love with Almería!
+
+![Almería](https://upload.wikimedia.org/wikipedia/commons/thumb/c/c8/Almer%C3%ADa%2C_Spain_-_panoramio_-_antocon.jpg/800px-Almer%C3%ADa%2C_Spain_-_panoramio_-_antocon.jpg){:width="100%"}
diff --git a/content/pages/accommodation-others.md b/content/pages/accommodation-others.md
new file mode 100644
index 0000000..47ac7c8
--- /dev/null
+++ b/content/pages/accommodation-others.md
@@ -0,0 +1,139 @@
+Title: Other accommodation alternatives
+Date: 20180403
+Authors: olea
+
+One of the Almería city advantages is not being a massive tourstic place (think Barcelona, Málaga or Palma 
de Mallorca, visited by millions each year) but provides a good hosting offering with several qualities until 
4 stars. Consider than 4 stars hotels in Spain can be quality similar to 5 stars ones in other countries.
+
+You can use platforms such as Booking, TripAdvisor or Trivago to search for the accommodation you like.
+
+Here is a list for your reference
+
+### 4 stars hotels
+<div class="table-responsive">
+    <table class="table table-striped table-bordered schedule">
+        <tbody>
+            <tr>
+                <td><img src="/images/nuevo-torreluz.jpg" width="300px" alt="Nuevo Torreluz"></td>
+                <td>
+                    <a href="http://en.nuevotorreluz.com/"; target="_blank">Nuevo Torreluz</a>,
+                    <a href="https://www.openstreetmap.org/node/1711184296"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/nh.jpg" width="300px" alt="NH Ciudad de Almería"></td>
+                <td>
+                    <a href="http://www.nh-hotels.com/hotels/almeria"; target="_blank">NH Ciudad de 
Almería</a>,
+                    <a href="https://www.openstreetmap.org/way/27152916"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/acmarriot.jpg" width="300px" alt="AC Hotel Almería Marriot"></td>
+                <td>
+                    <a href="http://www.marriott.com/hotels/travel/leial-ac-hotel-almeria/"; 
target="_blank">AC Hotel Almería Marriot</a>,
+                    <a href="https://www.openstreetmap.org/node/3546471699"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/hotel-catedral-almeria.jpg" width="300px" alt="Hotel Catedral"></td>
+                <td>
+                    <a href="http://www.hotelcatedral.net"; target="_blank">Hotel Catedral</a>,
+                    <a href="https://www.openstreetmap.org/node/2697637577"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/elba.jpg" width="300px" alt="Elba Almería Hotel"></td>
+                <td>
+                    <a href="https://www.hoteleselba.com/en/hotel-elba-almeria-business-convention"; 
target="_blank">Elba Almería Hotel</a>,
+                    <a href="https://www.openstreetmap.org/node/442706297"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/tryp-indalo.jpg" width="300px" alt="Tryp Indalo Almería"></td>
+                <td>
+                    <a href="https://www.melia.com/en/hotels/spain/almeria/tryp-indalo-almeria-hotel/"; 
target="_blank">Tryp Indalo Almería</a>,
+                    <a href="https://www.openstreetmap.org/node/442686279"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/sercotel.jpg" width="300px" alt="Hotel Sercotel Gran Fama"></td>
+                <td>
+                    <a href="http://en.hotelgranfama.com/"; target="_blank">Hotel Sercotel Gran Fama</a>,
+                    <a href="https://www.openstreetmap.org/node/2134900027"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/avenida.jpg" width="300px" alt="Avenida Hotel Almería"></td>
+                <td>
+                    <a href="http://www.avenidahotelalmeria.com/en/"; target="_blank">Avenida Hotel 
Almería</a>,
+                    <a href="https://www.openstreetmap.org/way/505032860"; target="_blank">Directions</a>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
+
+### 3 stars hotels
+<div class="table-responsive">
+    <table class="table table-striped table-bordered schedule">
+        <tbody>
+            <tr>
+                <td><img src="/images/costasol.jpg" width="300px" alt="Hotel Costasol"></td>
+                <td><a href="http://www.hotelcostasol.com/en/"; target="_blank">Hotel Costasol</a></td>
+            </tr>
+        </tbody>
+    </table>
+</div>
+
+
+
+### 2 stars hotels
+<div class="table-responsive">
+    <table class="table table-striped table-bordered schedule">
+        <tbody>
+            <tr>
+                <td><img src="/images/hotel-torreluz-centro-almera-011.jpg" width="300px" alt="Torreluz 
Centro"></td>
+                <td>
+                    <a href="http://www.torreluz.com/es/alojamiento-torreluz-centro"; 
target="_blank">Torreluz Centro</a>,
+                    <a href="https://www.openstreetmap.org/node/1730264907"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/embajador.jpg" width="300px" alt="Embajador"></td>
+                <td>
+                    <a href="http://www.hotelembajador.es/en/"; target="_blank">Embajador</a>,
+                    <a href="https://www.openstreetmap.org/way/230511112"; target="_blank">Directions</a>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
+
+
+###  Aparthotels
+<div class="table-responsive">
+    <table class="table table-striped table-bordered schedule">
+        <tbody>
+            <tr>
+                <td><img src="/images/torreluz-centro-7.jpg" width="300px" alt="Aparthotels Torreluz"></td>
+                <td>
+                    <a href="http://www.torreluz.com/es/alojamiento-apartamentos-torreluz"; 
target="_blank">Aparthotels Torreluz</a>,
+                    <a href="https://www.openstreetmap.org/node/4950780938"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/16-9.jpg" width="300px" alt="16:9 Suites Ciudad"></td>
+                <td>
+                    <a href="http://dieciseisnovenossuites.com/suites"; target="_blank">16:9 Suites 
Ciudad</a>,
+                    <a href="https://www.openstreetmap.org/way/458511247"; target="_blank">Directions</a>
+                </td>
+            </tr>
+            <tr>
+                <td><img src="/images/16-9-2.jpg" width="300px" alt="16:9 Suites Playa"></td>
+                <td>
+                    <a href="http://dieciseisnovenossuites.com/apartamentos/169-suites-playa"; 
target="_blank">16:9 Suites Playa</a>,
+                    <a href="https://www.openstreetmap.org/way/44512016"; target="_blank">Directions</a>
+                </td>
+            </tr>
+        </tbody>
+    </table>
+</div>
diff --git a/content/pages/accommodation.md b/content/pages/accommodation.md
new file mode 100644
index 0000000..c6d2b1a
--- /dev/null
+++ b/content/pages/accommodation.md
@@ -0,0 +1,134 @@
+Title: GUADEC main accommodation
+Date: 20180403
+Authors: rugoma
+
+
+
+[![No vacancies at 
Civitas](/images/341654213_ea75287d82_m.jpg)](https://www.flickr.com/photos/51035614490@N01/341654213)
+
+Well, this happened: __there is no more rooms in Civitas__ for the core days.
+
+Please check the other [lodging alternatives](/pages/other-accommodation-alternatives.html) page.
+
+The nearest to Civitas accomodation places are:
+
+- 4 stars: [NH Ciudad de Almería](http://www.nh-hotels.com/hotels/almeria) 
([location](https://www.openstreetmap.org/way/27152916))
+- 2 stars: [Hotel Embajador](http://www.hotelembajador.es/en/) 
([location](https://www.openstreetmap.org/way/230511112))
+- [hostal](https://en.wikipedia.org/wiki/Hostal): [Hostal Estación](http://www.hostalestacion.com/en/) 
([location](https://www.openstreetmap.org/node/4433528855))
+
+
+
+## Civitas dormitory
+
+![Civitas 
building](http://www.residenciacivitas.com/wp-content/uploads/2017/04/PORTADA-INAUGURACI%C3%93N-CIVITAS.jpg){:width="300px"
 align="right"}
+
+
+The main option and our recommended accommodation for this year is [Residencia 
Civitas](http://www.residenciacivitas.com/en/) (view the [promotional 
video](http://www.youtube.com/watch?v=v0PAAprhc_U)).
+
+Civitas is a students dormitory with enough space for all GUADEC attendees and with great 
[facilities](http://www.residenciacivitas.com/en/facilities-civitas-residence/). It is about 5 minutes away 
from the bus and train station. It is in a great location because of the transport connections to the 
university and also with the center of Almería.
+
+If you are looking for someone to share a room with, you can [list yourself or get in touch with people 
using this wiki page](https://wiki.gnome.org/GUADEC/2018/Accommodation).
+
+## Price
+
+GUADEC attendes have a special price for Civitas dormitory:
+
+### Single room
+![Single room on 
Civitas](http://www.residenciacivitas.com/wp-content/uploads/2015/09/Instalaciones-habitacion-civitas-01.jpg){:width="200px"
 align="right"}
+
+- 32.75 € per night, breakfast included
+- 42.10 € per night, breakfast and evening dinner included
+
+
+
+
+### Twin room
+
+- 46.75 € per night, breakfast included
+- 56.10 € per night, breakfast and evening dinner included
+
+![Twin room on 
Civitas](http://www.residenciacivitas.com/wp-content/uploads/2015/09/Instalaciones-habitacion-civitas-05.jpg){:width="200px"
 align="right"}
+
+When making your reservation, remember that there is dinner available at some of the planned evening events.
+
+
+## Sharing a twin room
+
+You want to share a twin room but travel alone? Add yourself to the the list at [dedicated wiki 
page](https://wiki.gnome.org/GUADEC/2018/Accommodation).
+
+
+## Common rooms
+
+Each floor has a common room with where you can relax and chat with other attendees.
+
+<!-- ## Sponsored accommodation -->
+
+<!-- **People requesting accommodation sponsorship should not book their own accommodation.** -->
+
+
+## Booking process
+
+In order to book a room and get the GUADEC rates, send an email to recepcion residenciacivitas com with 
"GUADEC 2018 reservation" and use the template below when making the reservation, remove the options you 
don't want from the two "I want a:" sections. Prices are per room/per night.
+
+> Dear Residencia Civitas,
+>
+> My name is FULL_NAME and I want to make a reservation for the GUADEC 2018 conference at the University of 
Almería.
+>
+> I want a:
+>   - Single room
+>   - Double (two beds) room, for me and FULL_NAME_2
+>
+> Dates:
+>    - check-in day:
+>    - check-out day:
+>
+> And I want:
+>    - Half board (breakfast and evening dinner)
+>    - Bed and Breakfast
+>
+>    Please confirm the reservation.
+>
+>    Kind regards,
+>
+>    NAME
+
+Advertisement: When you make your reservation, you need to pay 50% in order to secure it. The payment must 
be done 15 days before your arrival. If you're waiting for your VISA, mention it in the email and the 
dormitory will not request the 50%.
+
+## Address
+
+Calle Fernán Caballero, 1, Almería (Spain).
+
+
+## How to arrive
+
+### From the airport
+
+#### By bus
+
+1. The bus stop at the airport is the number 188 (you can check the [wait 
time](http://m.surbus.com/tiempo-espera/parada/188)).
+1. You need [to take Line 30](http://www.surbus.com/inicio.aspx?cat=0&id=30) (1,05 €).
+1. Line 30 connects the city, the airport and the suburbs of Retamar (end of line). Since the bus stop is 
the same in both directions asks bus driver it's going back to the city. If not, you can choose either get 
the bus and pay again at end of line or wait till the bus take the route back from the suburbs.
+1. Get off at "Estación Intermodal", bus stop #292 (you can [check the wait 
time](http://m.surbus.com/tiempo-espera/parada/292)). This is just [outside the bus and train 
station](https://commons.wikimedia.org/wiki/Category:Almer%C3%ADa_train_station#/media/File:Antigua_estaci%C3%B3n_de_ferrocarril_de_Almer%C3%ADa.JPG).
+1. Walk 5 minutes to Civitas (check the [OpenStreetMap 
route](http://www.openstreetmap.org/directions?engine=mapzen_foot&route=36.83520%2C-2.45601%3B36.83752%2C-2.44828#map=17/36.83641/-2.45216)).
+
+#### By taxi
+
+You can use the PideTaxi application:
+
+- [web app](https://pidetaxi.es/book_taxi)
+- [smartphone app](https://pidetaxi.es/apps)
+
+Or phone / Telegram Whatsapp at: +34667226122
+
+If you have a problem to choose the correct destination use the alternative «Nuestra Señora de Montserrat, 
102, Almería».
+
+### From CIVITAS to GUADEC
+
+![Surbus Gregorio 
Mara](https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG/320px-L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG){:align="right"
 width="200px"}
+
+For the core days the conference will setup a direct bus from CIVITAS to the campus. We'll announce the 
precise time a few days before the conference.
+
+The bus will make stops at:
+
+- at [CIVITAS residence](https://goo.gl/maps/ZG5H9jTbAmL2);
+- at [the intermodal station](https://goo.gl/maps/pJn6U7swo8C2) (the bus/train central station).
diff --git a/content/pages/code-of-conduct.md b/content/pages/code-of-conduct.md
new file mode 100644
index 0000000..ab9e091
--- /dev/null
+++ b/content/pages/code-of-conduct.md
@@ -0,0 +1,134 @@
+Title: Code of conduct
+Date: 20180219
+
+This text documents what you can expect from the GNOME community when you attend GUADEC and, in turn, what 
we expect from you.
+
+This document has been agreed to by the local GUADEC organisation team.
+
+GUADEC is a welcoming and friendly event, during which attendees often make
+friends and join the GNOME community. GUADEC organisers are dedicated to
+providing a safe and harassement-free conference experience for everyone. To
+help set expectations and standards for the event, we ask all attendees,
+organizers and sponsors to follow this code of conduct (CoC) at all conference
+venues and conference-related social events.
+
+We ask you to be kind and respectful to others. Keep all communication
+appropriate for the audience, including people of different ages and different
+cultural backgrounds. GUADEC attendees come from all over the world, so
+something that you consider appropriate may not be appropriate to someone else.
+Do not insult or put down other attendees. Remember that sexist, racist or
+discriminatory language and imagery are not appropriate.
+
+We believe that people generally mean well. Excepting strong evidence to the
+contrary, we ask that you do the same. We favour communication over
+confrontation: most issues that arise during a conference (as with day to day
+contribution to any software project) can be resolved by communication between
+the affected parties.
+
+However, people do make mistakes. People are capable of engaging in thoughtless
+actions and are capable of making thoughtless remarks. Sometimes these actions
+and words cross a line. Even if you are not yourself offended by this
+behaviour, we ask that you discretely remind people that others may be. Be
+careful to not engage in actions that may escalate the situation.
+
+If you observe or experience any behaviour that you consider to be offensive or
+harassing, you can talk to or file a formal complaint with any member of the
+support team. The support team will be available to help you in a number of
+ways. This includes, but is not limited to, listening to you, mediating between
+you and another attendee, and helping you with the complaint process. Any
+communication will remain confidential and be taken seriously. All reports will
+be investigated. We do not engage in public shaming of any kind and we ask the
+same of you.
+
+The GUADEC organisers will take any actions that they consider appropriate for
+a report. This includes, but is not limited to:
+
+* Ask the person concerned to stop or change their behaviour
+* Ask the person concerned to leave the venue or event immediately for the remainder of the day
+* Ask the person concerned to leave immediately and prohibit them from returning to GUADEC
+* Help you report the incident to the local authorities
+
+#### Contacts:
+
+* GUADEC Help Telephone: +34 695 754 017
+* Email: code-of-conduct gnome org
+
+
+#### Other useful numbers/links:
+
+* Emergency number for police, fire department, or ambulance: 112
+
+## Incident response guidelines
+
+Should you observe or experience behaviour that is disrupting to the friendly
+environment of the event then please get into contact with our support team
+about it. In some cases this may even make sense for seemingly minor incidents
+if the observed behaviour may become harassing through frequent repetition.
+
+If an ongoing conflict is observed then please consult with the support team
+immediately and try to separate the involved parties if possible (if police
+intervention is in order do not hesitate to call them directly). The support
+team will try to reinstate the peace and investigate the incident afterwards by
+taking reports from everyone involved and observing third parties.
+
+The support team and organisers shall assist any party who wants to press
+charges by notifying and guiding them to the relevant authorities. The support
+team should offer further assistance to all parties (e.g. by contacting a
+friend, arranging an escort) to help them deal with the aftermath of an
+incident.
+
+Enforcement actions will usually only be taken be taken by the organisers once
+a written report is submitted by the support team. Any person at the receiving
+end of such action shall be given a chance to dispute the claims against them.
+Failure to cooperate with the organisers will result in immidate actions and
+may also result in further actions including criminal charges if applicable.
+
+The GUADEC organisers commit to publish an anonymized summary about the nature
+of reported incidents and actions that were taken.
+
+
+### Responding to incidents during Presentations
+
+Presentations or similar events should not be interrupted unless there are
+major incidents that are of longer duration or happen repeatedly. If the
+presentation is already being interrupted due to an incident (e.g. medical) or
+if the GUADEC organizers, a support team member, or a volunteer decides to
+interrupt it in response to an incident, then the video streaming should be
+stopped or at least the audio muted.
+
+If you need to interrupt the presentation to respond to an incident, then
+remember to stay polite while doing so. In the case of a presentation being
+stopped entirely the presenter should be given a chance to quickly conclude it
+for the local audience and for streaming purposes if possible.
+
+The GUADEC organisers may decide to not distribute recordings of presentations
+further because of incidents or for other reasons.
+
+
+### Taking reports
+
+Taking reports is important to understand what happened and a basis for deciding what further actions might 
be taken. Support team members shall take reports from all involved parties if possible. Do not rush when 
taking reports and ensure that you take the report in an environment that protects everyone’s privacy and is 
reassuring.
+
+Please ensure that the report accurately describes what happened and clearly marks anything which has not 
been directly observed but is of a notional nature. If possible the report should include information about
+
+* the time and date of the incident,
+* the identity of involved parties,
+* possibly third parties who may have observed the incident,
+* a description of the observed behaviour,
+* the circumstances surrounding the incident including
+* actions that were done in response to it, and
+* notes on additional privacy constraints from the reporter.
+
+Not all of this information will always be available and the reporter may decide to withhold any information 
without reason. Do not press the person for details but inform them that they can return at a later point. 
Even an incomplete report may be helpful.
+
+The reporter may abort the process at any time. The report will be kept private and only handled by the 
organisers and support team members. The reporter may ask for the contained information not to be used as a 
basis for any further actions such as questioning an alleged offender and deciding on enforcement.
+
+
+## Privacy statement
+
+GUADEC will protect the privacy of all individuals at all points. Private information will not be disclosed 
to third parties with the only exception listed below.
+
+All copies of reports shall be surrendered to the conference organisers and the reporting person by support 
team members. Support team members or GUADEC organisers shall not retain personal copies of reports or other 
private data connected to them. Private data must not be transferred to third party services (including the 
GNOME Foundation infrastructure). Documents related to reports
+and incidents shall be destroyed once they are not needed anymore or at the latest two years after the 
conference.
+
+The GUADEC organisers reserve the right to create a public report outlining the incidents that were 
reported. In some cases names of alleged offenders may be shared with third parties for future preventive 
measures (e.g. a warning to next years GUADEC organisers). GUADEC will not disclose detailed information from 
reports to any third party including the GNOME Foundation or law enforcement agencies unless required by law 
or authorized by the reporter.
diff --git a/content/pages/contact.md b/content/pages/contact.md
new file mode 100644
index 0000000..2fe2826
--- /dev/null
+++ b/content/pages/contact.md
@@ -0,0 +1,8 @@
+Title: Contact
+Date: 20180219
+
+GUADEC 2018 is organized by the __Club de Cacharreo__ association, a Spanish non-profit NGO, supported by 
the [GNOME Foundation](https://gnome.org/foundation/).
+
+* Ismael Olea, the lead organizer, can be contacted via phone at +34 695 754 017. For visa requests only, 
send him an email at [olea gnome org](mailto:olea gnome org).
+* For conference issues, please get in touch on the [GUADEC mailing 
list](https://mail.gnome.org/mailman/listinfo/guadec-list).
+* For sensitive issues use the private mailing list [guadec-organization gnome 
org](mailto:guadec-organization gnome org).
diff --git a/content/pages/how-to-sponsor.html b/content/pages/how-to-sponsor.html
new file mode 100644
index 0000000..b455c7f
--- /dev/null
+++ b/content/pages/how-to-sponsor.html
@@ -0,0 +1,69 @@
+<html>
+
+<head>
+       <title>How to sponsor</title>
+       <meta name="date" content="20180407" />
+</head>
+
+<body>
+       <p>Being involved with GUADEC gives you a number of benefits. Do you use technologies like GStreamer 
or GTK+? This is a great
+               place to get involved in their development. Are you looking to hire? Showing commitment to 
open source helps you attract
+               talented developers. If you want to promote your company, this is a way to have your logo 
seen across the world.</p>
+       <p>For any questions regarding sponsorship, please contact us at
+               <a href="mailto:sponsors guadec org">sponsors guadec org</a>
+       </p>
+       <div class="row">
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-1.jpg" alt="Meet key contributors">
+                       </p>
+                       <h3>Meet key contributors</h3>
+                       <p>GUADEC is a great opportunity to meet contributors and users of one of the leading 
free and open source technology platforms.</p>
+               </div>
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-2.jpg" alt="Influence product direction">
+                       </p>
+                       <h3>Influence product direction</h3>
+                       <p>Sponsoring and attending GUADEC not only gives you advance information on GNOME’s 
plans for the coming year, but provides
+                               you a voice in shaping them.</p>
+               </div>
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-3.jpg" alt="Access technical talent">
+                       </p>
+                       <h3>Access technical talent</h3>
+                       <p>Experienced developers from around the globe attend GUADEC. Meet business partners 
who can help you achieve your technical
+                               goals.
+                       </p>
+               </div>
+       </div>
+       <div class="row">
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-4.jpg" alt="Encourage technology adoption">
+                       </p>
+                       <h3>Encourage technology adoption</h3>
+                       <p>GUADEC has been a site for product launches, and a great place to encourage 
developers to use new technologies.</p>
+               </div>
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-5.jpg" alt="Contribute to the development of 
GNOME technologies">
+                       </p>
+                       <h3>Contribute to the development of GNOME technologies</h3>
+                       <p>Help the development of new features and components. GUADEC hosts planning and 
coding sessions, as well as technology
+                               and interoperability meetings.</p>
+               </div>
+               <div class="col col-sm-12 col-lg-4">
+                       <p>
+                               <img src="/images/how-to-sponsor-6.jpg" alt="Give back to free and open 
source software">
+                       </p>
+                       <h3>Give back to free and open source software</h3>
+                       <p>You’ll be recognized not only as a sponsor of GUADEC, but also as a supporter of 
free software, the GNOME project, and
+                               the ideals on which these are founded.</p>
+               </div>
+       </div>
+       <p>For more information, please see the <a href="/images/conference-brochure-2018-web.pdf" 
target="_blank">GUADEC 2018 sponsorship brochure</a>.</p>
+</body>
+
+</html>
\ No newline at end of file
diff --git a/content/pages/legal.md b/content/pages/legal.md
new file mode 100644
index 0000000..f3d37a3
--- /dev/null
+++ b/content/pages/legal.md
@@ -0,0 +1,6 @@
+Title: Legal
+Date: 20180219
+
+## This content is still in development
+
+We are working to give you the information you want as soon as possible. Please check this page again after 
some days.
diff --git a/content/pages/map.md b/content/pages/map.md
new file mode 100644
index 0000000..b97a3cb
--- /dev/null
+++ b/content/pages/map.md
@@ -0,0 +1,210 @@
+Title: Map
+Date: 20180615
+
+<!-- mapbox and osmtogeojson scritps and css -->
+<link rel='stylesheet' href='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.css' />
+<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v0.44.1/mapbox-gl.js'></script>
+<script src="https://tyrasd.github.io/osmtogeojson/osmtogeojson.js";></script>
+<script src="https://cdn.jsdelivr.net/npm/@mapbox/polyline@1.0.0/src/polyline.min.js";></script>
+<script src="https://cdnjs.cloudflare.com/ajax/libs/tinycolor/1.4.1/tinycolor.min.js";></script>
+
+<script src='/theme/js/guadec-map/guadec-map.js'></script>
+
+<style>
+    #map {
+        margin: 0;
+        height: 600px;
+        width: 100%;
+    }
+    .mapboxgl-popup-content a {
+        color: #4a86cf;
+        text-decoration-line: none;
+    }
+    .mapboxgl-popup-content ul {
+        padding-left: 18px;
+    }
+    .osm-source{
+        font-size: 0.7em;
+    }
+    .mapboxgl-popup-tip{
+        display:none;
+    }
+    .mapboxgl-popup-content{
+        padding: 5px;
+    }
+    .mapboxgl-popup-anchor-bottom .mapboxgl-popup-content{
+        border: 1px solid #4a86cf;
+    }
+    .mapboxgl-popup-anchor-top .mapboxgl-popup-content{
+        background-color: #B4C6DD;
+    }
+    .mapboxgl-popup-content p {
+        margin: 0;
+        max-width: 100px;
+    }
+    .mapboxgl-popup-content h3 {
+        font-size: 1rem;
+        margin-top: 5px;
+    }
+    .mapboxgl-popup-close-button{
+        color: #4a86cf;
+    }
+</style>
+
+<div id="map">
+</div>
+
+<script type="module">
+    /* parameters */
+    var options = {/* List of ways to include in the map */
+        osm_ways : [
+            { osm_id: 27152910, name: 'Railway Station', icon: 'rail-45'}, // almeria railway
+            // 27152911, // Estación intermodal
+            { osm_id: 27152911, icon: 'bus-45'}, // Estación intermodal
+            { osm_id: 29220363, icon: 'gnome-guadec-red'}, // almeria university
+            { osm_id: 435775764, icon: 'lodging-45'}, // Civitas
+            { osm_id:37923960, icon: 'airport-45'}, // airport
+            { osm_id: 36406179, name: 'UAL Parking', icon: 'parking-45'}, // UAL parking
+            { osm_id: 509640566, name: 'Patio de los naranjos', icon: 'bar-45'}, // Patio de los naranjos
+            { osm_id: 187403583, icon: 'bar-45'}, // terraza del mar
+            
+            { osm_id: 27155530, name: 'Alcazaba meeting point', icon: 'marker-45'},
+            { osm_id: 27018547, name: 'Alcazaba de Almería', icon: 'gnome-guadec-yellow'},
+            { osm_id: 37639082, name: 'Auditorium', icon: 'marker-45'},
+            { osm_id: 37639116, name: 'Conference Room', icon: 'marker-45'},
+            { osm_id: 37638898, name: 'Aula magna', icon: 'marker-45'},
+            { osm_id: 37639300, name: 'University cafeteria', icon:'restaurant-45'},
+        ],
+        /* List of nodes to include in the map */
+        osm_nodes : [
+            { osm_id: 2870058034, name: 'Intermodal bus stop',icon: 'bus-45'}, // 292
+            { osm_id: 974730957, icon: 'bus-45'}, // 144
+            { osm_id: 469474242, icon: 'bus-45'}, // 71
+            { osm_id: 469474241, icon: 'bus-45'},  //56
+            { osm_id: 2306864400, icon: 'bus-45'}, 
+            { osm_id: 1304074112, name: 'Airport bus stop',icon: 'bus-45'}, // 188
+            { osm_id: 999522025, name: 'ATM', icon: 'bank-45'}, // ATM machine
+            { osm_id: 5732671649, icon: 'rocket-45'},
+            { osm_id: 4441572589, icon: 'cafe-45'},
+            { osm_id: 975927412, icon: 'cafe-45'},
+            { osm_id: 975928504, icon: 'cafe-45'},
+            { osm_id: 975927743, icon: 'cafe-45'},
+            { osm_id: 4418928340, name: 'La Bambalina', icon: 'restaurant-45'},
+            { osm_id: 3421378813, name: 'Bella Ciao', icon: 'restaurant-45'},
+            { osm_id: 159008541, name: 'El Rincon de Basi', icon: 'restaurant-45'},
+            { osm_id: 5741050051, name: 'Scondite', icon: 'restaurant-45'},
+            { osm_id: 4414078515, name: 'Jauja', icon: 'restaurant-45'},
+            { osm_id: 27197952, name: 'Mr Beers', icon: 'restaurant-45'},
+            { osm_id: 4498384277, name: 'Piscolabis', icon: 'restaurant-45'},
+            { osm_id: 4523577353, name: 'Vintage54', icon: 'restaurant-45'},
+        ],
+        /* 
+            list of routes to render 
+            FROM and TO need are OSM node identifiers
+            It's BETTER if all nodes are already in the
+            osm_nodes list but not mandatory.
+        */
+        routes : [
+            {
+                waypoints: [2870058034, 435775764, 974730957],
+                title: 'GUADEC bus',
+                description: 'GUADEC direct bus route',
+                color: '#f00'
+            },
+            {
+                waypoints: [2306864400, 27155530],
+                method: 'walking',                 
+                title: 'to the castle',
+                description: 'Walk route from the bus stop to the visit starting point',
+                color: '#526635'
+            },
+            {
+                waypoints: [27155530, 5732646949],
+                method: 'walking', 
+                title: 'to the party',
+                description: 'Walk route from the castle to the party',
+                color: '#5c3566'
+            },
+            {
+                waypoints: [435775764, 187403583],
+                method: 'walking', 
+                title: 'to the beach party',
+                description: 'Walk route from Civitas to the chiringuito',
+                color: '#006dff'
+            }            
+        ],
+        /* Basemap Styles
+        OpenMapTiles https://openmaptiles.github.io/positron-gl-style/style-cdn.json
+        CARTO https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json
+        */
+        basemap_style : 'https://basemaps.cartocdn.com/gl/voyager-gl-style/style.json',
+        /* initial center and zoom level, you can use bboxfinder.com to find proper values */
+        center : [-2.421,36.823],
+        zoom   : 12,
+        /* Main color to use anywhere */
+        main_color : '#4a86cf',
+        /* Icon for the points ont the map */
+        icon : 'gnome-guadec-blue',
+        /* White list of properties to allow to
+        be displayed in the popup, order matters! */
+        popup_properties : [
+            'description',
+            'shop','amenity','wheelchair',
+            'highway', 'network', 'bench', 'shelter', 'ref',
+            'adr:street', 'picture',
+            'website','wikidata','wikipedia'
+        ],
+        mapbox_token :  
'pk.eyJ1IjoieHVyeG9zYW56IiwiYSI6ImNqaXk4NW40MTA3NWUzcG5vMjlobWk2dGIifQ.iI-Ns8Qh5uEg9dDwZnnecw',
+        tweak_style : function(style,options){
+            style['name'] = 'guadec_voyager';
+            style['id'] = 'guadec_voyager';
+            style['layers'] = style.layers.filter( l => l.id != 'place_suburbs' && l.id != 'building-top');
+            var guadec_light_color =  tinycolor(options.main_color).lighten(35).toHexString();
+
+            var building_layer = style.layers.filter(l => l.id == 'building');
+            if ( building_layer.length ==1 ){
+                building_layer[0].paint['fill-color'] = guadec_light_color;
+            }
+
+            return style
+        },
+        /* Try to detect development environment */
+        environment : window.location.href.search('localhost') != -1 ? 'DEV' : 'PROD'
+    };
+
+    var guadec_map = new GuadecMap(options);
+    var map = null;
+
+    // Promise to load the map
+    var get_map = new Promise((resolve,reject)=>{
+        // Get the map
+        guadec_map.init_map().then(map => {
+            // Do some style tweaks and then return it
+            map.on('load',function(){
+                resolve();
+            });
+        });
+    });
+
+    // Promise to load the data from OSM
+    var get_data = new Promise((resolve,reject) => {
+        guadec_map.fetch_data().then(osm_data => {
+            guadec_map.process_osm_data(osm_data);
+            resolve();
+        }).catch(error =>reject(error));
+    });
+
+    // When map and OSM data are retrieved, we can load POIS and Routes
+    Promise.all([
+        get_map,
+        get_data
+    ]).then(() => {
+        // Load the Routes
+        guadec_map.load_routes();
+        // Load the POIS
+        guadec_map.load_pois();
+    }).catch(error => console.log(error));
+
+    // make the map a global for testing
+    window.guadec_map = map;
+</script>
diff --git a/content/pages/materials.md b/content/pages/materials.md
new file mode 100644
index 0000000..135d4cc
--- /dev/null
+++ b/content/pages/materials.md
@@ -0,0 +1,37 @@
+Title: Materials
+Date: 20180219
+
+Here we provide some materials to be used by attendees or speakers.
+
+
+## Badges
+
+You can use these badges for e.g. blogpost to promote the fact that you are going to GUADEC or are even 
speaking at the conference!
+
+
+<figure>
+  <img src="/images/2018-GUADEC badge.png" width="400px" alt="GUADEC 2018 badge">
+  <figcaption> GUADEC 2018 badge (<a href="/images/2018-GUADEC badge.svg">svg source </a>)</figcaption>
+</figure>
+<figure>
+  <img src="/images/2018-GUADEC badge-going.png" width="400px" alt="Going to GUADEC 2018 badge">
+  <figcaption>Going to GUADEC 2018 badge (<a href="/images/2018-GUADEC badge-going.svg">svg source 
</a>)</figcaption>
+</figure>
+
+
+<figure>
+  <img src="/images/2018-GUADEC badge-speaking.png" width="400px" alt="Speaking at GUADEC 2018 badge">
+  <figcaption> Speaking at GUADEC 2018 badge (<a href="/images/2018-GUADEC badge-speaking.svg">svg 
source</a>)</figcaption>
+</figure>
+
+
+<!-- 
+## Posters
+
+We have a 
[poster](https://github.com/gnome-design-team/gnome-marketing/tree/master/events/guadec/2017/posters-and-banners)
 that can be used to promote GUADEC 2017.
+--> 
+
+## Slide Templates
+
+We have slide templates for GUADEC available in the [presentation-templates 
repository](https://git.gnome.org/browse/presentation-templates). The template can be used with Markdown or 
LaTeX (via Pandoc). Any help with further formats is appreciated and can be added to the repository.
+
diff --git a/content/pages/photo-policy.md b/content/pages/photo-policy.md
new file mode 100644
index 0000000..6b27872
--- /dev/null
+++ b/content/pages/photo-policy.md
@@ -0,0 +1,50 @@
+Title: Photo Policy
+Date: 20180704
+
+Photography is a common part of GNOME events. These events are an
+important opportunity for GNOME to get images for marketing and
+fundraising purposes, and people therefore may be taking photographs
+at our request or encouragement. There may also be press photographers
+present.
+
+**We recognize that some attendees might not want to have their
+picture taken**, or that it might make them feel uncomfortable. If
+this applies to you, the GUADEC organisers will do their best to
+ensure that your wishes are complied with.
+
+### Guidelines for attendees
+
+#### Badges
+
+At the registration booth there will be badges available in two
+colors:
+
+* BLUE - you are okay with your photo being taken
+* ORANGE - you are **NOT** okay with your photo being taken
+
+Please choose the badge color that respects your wishes.  We expect
+photographers to be observant and respect this.
+
+#### At conference sessions
+
+At the rooms for conference sessions, there will be a designated
+sitting area for people who do not want their picture taken as part of
+group photos within the room; you are free to sit there if you don't
+want to be photographed.
+
+### Guidelines for photographers
+
+Don't take pictures of people who are wearing the ORANGE photo-free
+badge color.
+
+Don't take pictures that include the photo-free area of conference
+rooms.
+
+Please request permission from parents or guardians before taking
+pictures of minors. 
+
+If someone asks you not to take their picture, don't. If someone asks
+you to delete or un-publish a picture you have taken of them, politely
+comply.
+
+Thank you!
diff --git a/content/pages/schedule.md b/content/pages/schedule.md
new file mode 100644
index 0000000..daf4fe1
--- /dev/null
+++ b/content/pages/schedule.md
@@ -0,0 +1,123 @@
+Title: Schedule
+Date: 20180219
+
+The schedule is available in the Giggity Schedule Viewer app on Android devices 
([F-Droid](https://f-droid.org/packages/net.gaast.giggity/), [Google 
Play](https://play.google.com/store/apps/details?id=net.gaast.giggity)). Other apps may be able to import it 
in [Pentabarf XML format](https://2018.guadec.org/documents/schedule.xml).
+
+<div class="table-responsive">
+    <table class="table table-striped table-bordered schedule">
+        <thead class="thead-dark">
+            <tr>
+                <th scope="col"></th>
+                <th scope="col">Thursday 5th</th>
+                <th scope="col">Friday 6th</th>
+                <th scope="col">Saturday 7th</th>
+                <th scope="col">Sunday 8th</th>
+                <th scope="col">Monday 9th</th>
+                <th scope="col">Tuesday 10th</th>
+                <th scope="col">Wednesday 11th</th>
+            </tr>
+        </thead>
+        <tbody>
+            <tr>
+                <th scope="row"><a href="#core-days">Core days</a></th>
+                <td></td>
+                <td>☑</td>
+                <td>☑</td>
+                <td>☑</td>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+
+            <tr>
+                <th scope="row"><a href="https://wiki.gnome.org/GUADEC/2018/Hacking%20days";>Hacking & 
BoFs</a></th>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td>☑</td>
+                <td>☑</td>
+                <td>☑</td>
+            </tr>
+
+            <tr>
+                <th scope="row">Workshops</th>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td>☑</td>
+                <td></td>
+                <td></td>
+            </tr>
+
+            <tr>
+                <th scope="row">AGM</th>
+                <td></td>
+                <td></td>
+                <td>Evening</td>
+                <td></td>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+
+            <tr>
+                <th scope="row">Lightning talks</th>
+                <td></td>
+                <td>Interns</td>
+                <td></td>
+                <td>General</td>
+                <td></td>
+                <td></td>
+                <td></td>
+            </tr>
+
+            <tr>
+                <th scope="row"><a href="/pages/venue.html#direct-bus">GUADEC&nbsp;Bus&nbsp;Service 
(CIVITAS&nbsp;⇄&nbsp;campus)</a></th>
+                <td></td>
+                <td>⇄</td>
+                <td>⇄</td>
+                <td>⇄</td>
+                <td>→</td>
+                <td>→</td>
+                <td>→</td>
+            </tr>
+
+            <tr>
+                <th><a href="/pages/social-events.html">Social events</a></th>
+                <td><a href="/pages/social-events.html#welcome-party">Welcome party & pre-registration</td>
+                <td><a href="/pages/social-events.html#beach-party">Beach party & football game</td>
+                <td><a href="/pages/social-events.html#culture-show">Cultural show & picnic</a></td>
+                <td><a href="/pages/social-events.html#womens-dinner">Women's dinner</a></td>
+                <td></td>
+                <td></td>
+                <td>Outdoor tourism activites</td>
+            </tr>
+        </tbody>
+    </table>
+</div>
+
+<!--
+&nbsp;| Thursday 5th | Friday 6th | Saturday 7th | Sunday 8th  | Monday 9th | Tuesday 10th | Wednesday 11th  
+<<<<<<< Updated upstream
+------|:------------:|:----------:|:------------:|:-----------:|:----------:|:------------:|:--------------:
+Core days |          |          ☑ |            ☑ |           ☑ |            |              |  
+Hacking & BoFs |     |            |              |             |          ☑ |            ☑ | ☑
+AGM   |              |            |      Evening |             |            |              |
+Lightning talks |    |    Interns |              |     General |            |              |
+Lunches <br/> (at cafeteria)| | ☑ |            ☑ |           ☑ |          ☑ |            ☑ | ☑
+Bus service  <br/> (from CIVITAS<br/> to campus)|  | ☑ | ☑ | ☑ |            |              |  
+Planned childcare<br/> service |  | ☑ |        ☑ |           ☑ |          ☑ |            ☑ | ☑
+Social events | Welcome party<br /> & pre-registration  | Beach<br/> party | Cultural show<br/> & picnic |  
|  |  | Outdoor tourism<br/>activites
+-->
+
+# Workshops
+
+There are two workshops running on the 9th July in room 1 of the Aulario IV building (where registration is 
located).
+
+ * 10:30 - 13:30 : <a href="https://wiki.gnome.org/GUADEC/2018/Workshops/GitLab";>GitLab CI</a> by Carlos and 
Ralf (compulsory pre-registration on wiki page)
+ * 14:00 - 18:00 : <a href="https://wiki.gnome.org/GUADEC/2018/Workshops/Flatpak#preview";>Flatpak</a> by 
Alex (limited spaces, no pre-registration)
+
+<a name="core-days"> </a>
+<!-- AUTOGENERATED --><div class="schedule"><h3>Friday 06. July 2018</h3><table><thead><tr><td 
/><td>Auditorium</td><td>Aula Magna</td></tr></thead><tbody><tr><td>09:30</td><td class="break" 
colspan="2"><span id="200-registration" style="font-weight: 
bold">Registration</span></td></tr><tr><td>10:00</td><td class="talk"><span id="118-conference_opening" 
style="font-weight: bold">Conference opening</span><br />GUADEC Team</td><td /></tr><tr><td>10:30</td><td 
class="talk"><span id="50-ubuntus_journey_from_unity_to_gnome_shell" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-50-ubuntus_journey_from_unity_to_gnome_shell">Ubuntu's journey 
from Unity to GNOME Shell</a></span><br />Ken VanDine, Didier Roche</td><td /></tr><tr><td>11:00</td><td 
class="talk"><span id="32-gtk4_lightning_talks" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-32-gtk4_lightning_talks">GTK4 Lightning talks</a></span><br 
/>Benjamin Otte</td><td class="talk">
 <span id
 ="42-dealing_with_controversy__a_practical_guideline" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-42-dealing_with_controversy__a_practical_guideline">Dealing with 
controversy - a practical guideline</a></span><br />Sriram Ramkrishna</td></tr><tr><td>11:45</td><td 
class="break" colspan="2"><span id="201-break" style="font-weight: 
bold">Break</span></td></tr><tr><td>12:15</td><td class="talk"><span 
id="34-the_infamous_gnome_shell_performance" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-34-the_infamous_gnome_shell_performance">The infamous GNOME Shell 
performance</a></span><br />Jonas Ådahl, Carlos Garnacho</td><td class="talk"><span 
id="21-gnome_foundation_looking_into_the_future" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-21-gnome_foundation_looking_into_the_future">GNOME Foundation: 
Looking into the Future</a></span><br />Rosanna Yuen</td></tr><tr><td>13:00</td><td class="talk"><span id=
 "26-bett
 er_gtk_and_app_development_on_windows" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-26-better_gtk_and_app_development_on_windows">Better GTK+ and app 
development on Windows</a></span><br />Nirbheek Chauhan</td><td class="talk"><span 
id="39-product_management_in_open_source" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-39-product_management_in_open_source">Product Management in Open 
Source</a></span><br />Nick Richards</td></tr><tr><td>13:30</td><td class="break" colspan="2"><span 
id="202-lunch" style="font-weight: bold">Lunch</span></td></tr><tr><td>14:30</td><td class="talk"><span 
id="44-miracast_for_gnome" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-44-miracast_for_gnome">Miracast for GNOME</a></span><br 
/>Benjamin Berg</td><td class="talk"><span id="29-maxwell_embedding_widgets_in_webkit" style="font-weight: 
bold"><a href="/pages/talks-and-events.html#abstract-29-maxwell_embedding_widgets
 _in_webk
 it">Maxwell: embedding widgets in WebKit</a></span><br />Juan Pablo Ugarte</td></tr><tr><td>15:00</td><td 
class="talk"><span id="Open talk" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-Open talk">cancelled</a></span><br />to be announced on the 
day</td><td class="talk"><span style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-Open 
talk">cancelled</a></span><br />to be announced on the day</td></tr><tr><td>15:30</td><td class="talk"><span 
id="106-unconference-1" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-106-unconference-1">Implementing Phone UIs with 
GTK+</a></span><br />Adrien Plazas</td><td class="talk"><span id="107-unconference-1" style="font-weight: 
bold"><a href="/pages/talks-and-events.html#abstract-107-unconference-1">How to handle design 
critique</a></span><br />Nick Richards and Jakub Steiner</td></tr><tr><td>16:00</td><td class="break" 
colspan="2"><span id="203-break" style="font-weight
 : bold">
 Break</span></td></tr><tr><td>16:30</td><td class="talk"><span id="102-intern_and_newcomer_lightning_talks" 
style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-102-intern_and_newcomer_lightning_talks">Intern and newcomer 
lightning talks</a></span><br />Interns and newcomers</td><td /></tr><tr><td>17:30</td><td class="break" 
colspan="2"><span id="204-venue_closes" style="font-weight: bold">Venue 
closes</span></td></tr><tr><td>17:35</td><td /><td /></tr><tr><td>20:00</td><td class="break" 
colspan="2"><span id="121-beach_party" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-121-beach_party">Beach Party</a></span><br />GUADEC 
Team</td></tr></tbody></table><h3>Saturday 07. July 2018</h3><table><thead><tr><td 
/><td>Auditorium</td><td>Conference Room</td></tr></thead><tbody><tr><td>10:30</td><td class="talk"><span 
id="20-freedesktopsdk_the_future_of_linux_runtimes" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstrac
 t-20-fre
 edesktopsdk_the_future_of_linux_runtimes">Freedesktop-sdk, the future of Linux runtimes</a></span><br />Adam 
Jones, Valentin David</td><td class="talk"><span id="30-javascript_in_gnome_in_2018" style="font-weight: 
bold"><a href="/pages/talks-and-events.html#abstract-30-javascript_in_gnome_in_2018">Javascript in GNOME in 
2018</a></span><br />Philip Chimento</td></tr><tr><td>11:00</td><td class="talk"><span 
id="41-flathub__an_app_store_and_build_service_for" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-41-flathub__an_app_store_and_build_service_for">Flathub - An app 
store and build service for…</a></span><br />Robert McQueen &amp; Jorge García</td><td class="talk"><span 
id="25-making_a_phone_call_with_gnome" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-25-making_a_phone_call_with_gnome">Making a phone call with 
GNOME</a></span><br />Bob Ham</td></tr><tr><td>11:45</td><td class="break" colspan="2"><span id="205-break" s
 tyle="fo
 nt-weight: bold">Break</span></td></tr><tr><td>12:15</td><td class="talk"><span 
id="40-p2p_distribution_of_flatpaks_and_ostrees" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-40-p2p_distribution_of_flatpaks_and_ostrees">P2P Distribution of 
Flatpaks and OSTrees</a></span><br />Matthew Leeds</td><td class="talk"><span 
id="28-building_the_libre_desktop" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-28-building_the_libre_desktop">Building the Libre 
Desktop</a></span><br />Louisa Bisio</td></tr><tr><td>13:00</td><td class="talk"><span 
id="6-migrating_from_jhbuild_to_buildstream" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-6-migrating_from_jhbuild_to_buildstream">Migrating from JHBuild 
to BuildStream</a></span><br />Michael Catanzaro</td><td class="talk"><span id="47-plan_your_testing" 
style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-47-plan_your_testing">Plan your 
testing</a
</span>
 <br />Kat</td></tr><tr><td>13:30</td><td class="break" colspan="2"><span id="206-lunch" style="font-weight: 
bold">Lunch</span></td></tr><tr><td>14:30</td><td class="talk"><span id="16-thunderbolt_gnulinux_and_gnome" 
style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-16-thunderbolt_gnulinux_and_gnome">Thunderbolt, GNU/Linux and 
GNOME</a></span><br />Christian Kellner</td><td class="talk"><span 
id="3-translating_software_using_related_languages" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-3-translating_software_using_related_languages">Translating 
software using related languages</a></span><br />Rūdolfs Mazurs</td></tr><tr><td>15:00</td><td 
class="talk"><span id="108-unconference-1" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-108-unconference-1">Building Flatpak apps with 
Buildstream</a></span><br />Sam Thursfield</td><td class="talk"><span id="109-unconference-1" 
style="font-weight: bold"><a href
 ="/pages
 /talks-and-events.html#abstract-109-unconference-1">Input methods, wayland, and upstreams</a></span><br 
/>dcz</td></tr><tr><td>15:30</td><td class="talk"><span id="110-unconference-1" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-110-unconference-1">Slimbook Linux laptops</a></span><br 
/>Slimbook</td><td class="talk"><span id="111-unconference-1" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-111-unconference-1">Snap Package support in GNOME</a></span><br 
/>Robert Ancell</td></tr><tr><td>16:00</td><td class="break" colspan="2"><span id="207-break" 
style="font-weight: bold">Break</span></td></tr><tr><td>16:30</td><td class="talk"><span 
id="100-gnome_foundation_agm" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-100-gnome_foundation_agm">GNOME Foundation AGM</a></span><br 
/>GNOME Board</td><td /></tr><tr><td>18:30</td><td class="break" colspan="2"><span id="208-venue_closes" 
style="font-weight: bold
 ">Venue 
 closes</span></td></tr><tr><td>18:35</td><td /><td /></tr><tr><td>19:30</td><td class="break" 
colspan="2"><span id="122-cultural_show__picnic" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-122-cultural_show__picnic">Cultural show &amp; 
picnic</a></span><br />GUADEC Team</td></tr></tbody></table><h3>Sunday 08. July 
2018</h3><table><thead><tr><td /><td>Auditorium</td><td>Conference 
Room</td></tr></thead><tbody><tr><td>10:30</td><td class="talk"><span id="14-pipewire" style="font-weight: 
bold"><a href="/pages/talks-and-events.html#abstract-14-pipewire">PipeWire</a></span><br />Wim 
Taymans</td><td class="talk"><span id="33-have_you_ever_developed_for_a_gpu" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-33-have_you_ever_developed_for_a_gpu">Have you ever developed for 
a GPU?</a></span><br />Benjamin Otte</td></tr><tr><td>11:00</td><td class="talk"><span 
id="15-whats_happening_in_builder" style="font-weight: bold"><a href="/pag
 es/talks
 -and-events.html#abstract-15-whats_happening_in_builder">What's happening in Builder?</a></span><br 
/>Christian Hergert, Corentin Noël</td><td class="talk"><span 
id="2-design_of_an_ux_case_iot_integration_in_gnome" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-2-design_of_an_ux_case_iot_integration_in_gnome">Design of an UX 
case: IoT integration in GNOME.</a></span><br />Claudio Alexander Santoro 
Wunder</td></tr><tr><td>11:45</td><td class="break" colspan="2"><span id="209-break" style="font-weight: 
bold">Break</span></td></tr><tr><td>12:15</td><td class="talk"><span 
id="24-patterns_of_refactoring_c_to_rust" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-24-patterns_of_refactoring_c_to_rust">Patterns of refactoring C 
to Rust</a></span><br />Federico Mena Quintero</td><td class="talk"><span id="13-devops_for_gnome" 
style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-13-devops_for_gnome">DevOps for GNOM
 E</a></s
 pan><br />Carlos Soriano</td></tr><tr><td>13:00</td><td class="talk"><span 
id="5-glib_whats_new_and_whats_next" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-5-glib_whats_new_and_whats_next">GLib: What’s new and what’s 
next?</a></span><br />Philip Withnall</td><td class="talk"><span id="19-designing_gnome_mobile" 
style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-19-designing_gnome_mobile">Designing 
GNOME Mobile</a></span><br />Tobias Bernard</td></tr><tr><td>13:30</td><td class="break" colspan="2"><span 
id="210-lunch" style="font-weight: bold">Lunch</span></td></tr><tr><td>14:30</td><td class="talk"><span 
id="4-download_management_on_metered_connections" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-4-download_management_on_metered_connections">Download management 
on metered connections</a></span><br />Philip Withnall</td><td class="talk"><span 
id="10-simple_tricks_to_assess_and_improve_the_secu
 rity_o" 
 style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-10-simple_tricks_to_assess_and_improve_the_security_o">Simple 
tricks to assess and improve the security o</a></span><br />T̛̮ò̗b͎̈́i̧͐a̠̐s͓̒ 
̘̂M̧͋ṳ͂e̞͠ĺ̩l̟̍é̩r̛͉</td></tr><tr><td>15:00</td><td class="talk"><span id="112-unconference-1" 
style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-112-unconference-1">Breaking into 
and defending Linux – examples</a></span><br />dcz</td><td class="talk"><span id="113-unconference-1" 
style="font-weight: bold"><a href="/pages/talks-and-events.html#abstract-113-unconference-1">Endless 
Code</a></span><br />Philip Chimento</td></tr><tr><td>15:30</td><td class="talk"><span 
id="114-unconference-1" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-114-unconference-1">Building for humans: methods for improving 
usability</a></span><br />Robin</td><td class="talk"><span id="115-unconference-1" style="
 font-wei
 ght: bold"><a href="/pages/talks-and-events.html#abstract-115-unconference-1">How I secretly wish fonts 
worked (on GNOME)</a></span><br />Nate</td></tr><tr><td>16:00</td><td class="break" colspan="2"><span 
id="211-break" style="font-weight: bold">Break</span></td></tr><tr><td>16:30</td><td class="talk"><span 
id="103-lightning_talks" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-103-lightning_talks">Lightning talks</a></span></td><td 
/></tr><tr><td>18:00</td><td class="talk"><span id="119-conference_closing" style="font-weight: 
bold">Conference closing</span><br />GUADEC Team</td><td /></tr><tr><td>18:15</td><td class="break" 
colspan="2"><span id="212-venue_closes" style="font-weight: bold">Venue 
closes</span></td></tr></tbody></table><h3>Monday 09. July 2018</h3><table><thead><tr><td /><td>Room 
1</td></tr></thead><tbody><tr><td>10:30</td><td class="talk"><span id="123-gitlab_ci" style="font-weight: 
bold"><a href="https://wiki.gnome.org/GUADEC/2018/
 Workshop
 s/GitLab">GitLab CI</a></span><br />Carlos Soriano, Ralf</td></tr><tr><td>13:30</td><td class="break" 
colspan="1"><span id="213-lunch" style="font-weight: bold">Lunch</span></td></tr><tr><td>14:00</td><td 
class="talk"><span id="124-flatpak_workshop" style="font-weight: bold"><a 
href="/pages/talks-and-events.html#abstract-124-flatpak_workshop">Flatpak workshop</a></span><br />Alexander 
Larsson</td></tr><tr><td>18:00</td><td /></tr></tbody></table></div><!-- /AUTOGENERATED -->
diff --git a/content/pages/social-events.md b/content/pages/social-events.md
new file mode 100644
index 0000000..67f9e40
--- /dev/null
+++ b/content/pages/social-events.md
@@ -0,0 +1,149 @@
+Title: Social events
+Date: 20180219
+
+GUADEC is not only about the technical talks and hacking, it is also an opportunity for our community to 
gather together in other activities.
+
+<a name="welcome-party"></a>
+
+## Welcome and pre-registration party
+
+![party at civitas](/images/civitas-tapas.jpg){:width="300" align="right"}
+Date: __July 5th__, __21:00__ <br/>
+Place: [Civitas residence's patio](https://www.openstreetmap.org/way/435775764)
+
+Outdoors welcome to Almería dinning party to meet again with friends and newcomers.
+
+(Picture source: [Akademy 2017](https://dot.kde.org/2017/07/21/kde-arrives-almer%C3%ADa-akademy-2017)).
+
+## Newcomers lunch
+
+For the first lunch at Core Days in __July 6th__ we'll meet all the newcomers in a reserved place at the 
campus cafeteria. Enjoy your first GNOME lunch with a relaxing cup of gazpacho.
+
+<a name="womens-dinner"></a>
+
+## Women's Dinner
+
+![GNOME girl](/images/gnome_karate_girl_by_pookstar.png){:width="150" align="left"}
+
+The eighth annual women's dinner will take place at GUADEC 2018 on __Sunday, July 8th__. Women (cis and 
trans) and genderqueer people are invited to attend if interested. Having a women's event provides an 
additional opportunity for women in the community to meet each other, and establish a connection and a 
comfortable environment for discussing common issues. Please RSVP for the Women's Dinner by adding your name 
[to the wiki page](https://wiki.gnome.org/GUADEC/2018/WomensDinner).
+
+(GNOME Karate Girl [by pookstar](https://www.deviantart.com/pookstar/art/GNOME-Karate-Girl-143643760).)
+
+</br></br></br>
+
+<a name="beach-party"></a>
+
+## Beach party
+
+![Terraza del mar](/images/640px-Terraza_del_Mar_(front\).jpg){:width="300" align="right"}
+
+When: __July 6th__, __20:00__<br/>
+Place: [Terraza del mar](https://www.openstreetmap.org/way/187403583) and surroundings
+
+The place is about 35 minutes walking from Civitas and it's a beautiful restaurant at the beach. Around the 
place we'll do several activities.
+
+### Newcomers games
+
+For GNOME is important the feeling of community. So we are planning a set of activities and games for 
increase the sense of membership of our people with special focus on the new ones: strengthening the links 
with their mates and sharing experience from our best old-farts. More details soon.
+
+### Football game
+
+![Football 
Beach](https://upload.wikimedia.org/wikipedia/commons/thumb/5/54/F%C3%BAtbol_playa_%288181486225%29.jpg/640px-F%C3%BAtbol_playa_%288181486225%29.jpg){:width="250"
 align="right"}
+The traditional [football game](https://en.wikipedia.org/wiki/Association_football) that happens in every 
edition of GUADEC is schedule for __July 6th (Friday)__ at the Beach party. If you are interested in 
attending, please [signup in our wiki page](https://wiki.gnome.org/GUADEC/2018/Football) so we can plan the 
activities according to the expected number of attendees.
+
+### Paella dinner
+
+A great starting day requires a great dinner for our guests. Paella comes to help.
+
+![big paella](/images/320px-Paella_1719081168.jpg){:width="300" align="right"}
+
+The dinner will be an spectacle by itself: a big paella will be cooked in front of us by rice specialized 
cookers. Well have free drinks and lot of time to hangout at the beach, make sand castles and take a dip.
+
+The paella will be served with an special sangría made for us. You'll enjoy it, we bet.
+
+Picture source: [Charles Haynes](https://commons.wikimedia.org/wiki/File:Paella_1719081168.jpg).
+
+All in Terraza del mar, a beautiful [chiringuito](https://en.wikipedia.org/wiki/Chiringuito) on the shores 
of the Mediterranean.
+
+<blockquote class="instagram-media" data-instgrm-captioned 
data-instgrm-permalink="https://www.instagram.com/p/BkSJO87jFF9/"; data-instgrm-version="8" style=" 
background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 
rgba(0,0,0,0.15); margin: 1px; max-width:400px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); 
width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; 
margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" 
background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqj
 rTY0L8fx
 CxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; 
top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a 
href="https://www.instagram.com/p/BkSJO87jFF9/"; style=" color:#000; font-family:Arial,sans-serif; 
font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; 
word-wrap:break-word;" target="_blank">Fiesta!!! :D</a></p> <p style=" color:#c9c8cd; 
font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; 
overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">Una 
publicación compartida de <a href="https://www.instagram.com/chiringuitoterrazadel/"; style=" color:#c9c8cd; 
font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;" 
target="_blank"> Terraza del Mar</a> (@chiringuitoterrazadel) el <time style=" font-family:Arial,sans-serif; 
fo
 nt-size:
 14px; line-height:17px;" datetime="2018-06-21T10:33:38+00:00">21 Jun, 2018 a las 3:33 
PDT</time></p></div></blockquote> <script async defer src="//www.instagram.com/embed.js"></script>
+
+### GUADEC Ice Cream Death Match competition
+
+![GUADEC Ice Cream Death Match](/images/ice-cream-death-match-420x280.jpg){:width="200" align="left"}
+Because some customs should never be lost in GUADEC 2018 will recover yet'ol thrilling competition for the 
ones with the more cold heart and hot stomach. Do you dare?
+
+(Picture Copyright penguincakes, CC BY-NC-SA 2.0)
+
+<br/><br/>
+
+![wool bathing suit fron 1870](/images/187px-Bathing_suit_MET_1979.346.18ab.jpeg){:width="150" align="right"}
+
+### Swimsuit
+
+Bring swimsuit. Sure you'll want it.
+
+([Swimsuit picture source](https://commons.wikimedia.org/wiki/File:Bathing_suit_MET_1979.346.18ab.jpeg).)
+
+### Remark
+
+As we are sure we'll enjoy a nice weather we need to remark Almería is a windy city. From time to time we 
have some warm wind days not optimal for the beach experience. The good thing is the wind almost disapear at 
evening so we'll probably enjoy nice weather.
+
+<a name="culture-show"></a>
+
+## Culture show and picnic
+
+When:  __Sat 7th__
+
+How to overcome the beach party? Well: history and flamenco to the rescue.
+
+After the AGM we leave the campus to Civitas, to drop bags and change clothes, take again the bus and will 
stop in front of the port of Almería to  walk to the castle over the hill.  
+
+![Alcazaba de Almería](/images/guided-visit/320px-Alcazaba_de_Almería.jpg){:align="right"}
+
+### Guided visit to the Alcazaba castle
+
+
+![Gate of Justice](/images/guided-visit/360px-Entrada_Alcazaba_Almería.JPG){:width="150" align="left"}
+
+The city of Almería born around it's [alcazaba](https://en.wikipedia.org/wiki/Alcazaba_of_Almer%C3%ADa) 
(from the Arabic word al-qasbah),  when the Caliph of Cordoba, Abd ar-Rahman III, founded the caliphate naval 
base. The alcazaba is still the biggest muslim castle in Europe. 
+
+GUADEC 2018 offers you an special visit guided by ancient inhabitants of the castle (some of then 1000 years 
old!) through the three castle enclosures, from the Gates of Justice to the Christian modern castle.
+<br/><br/><br/>
+![](/images/guided-visit/Walkway_Alcazaba,_Almeria,_Spain.jpg){:width="150" }
+![](/images/guided-visit/PROMO-8-255x255.jpg){:width="150" }
+![](/images/guided-visit/PUBLICO-EN-GENERAL1-255x255.jpg){:width="150" }
+![](/images/guided-visit/UN-PASADO-FASCINANTE-2-255x255.jpg){:width="150" }
+
+
+
+The visit will start at __19:30__  from the [meeting point at the foot of the 
hill](https://www.openstreetmap.org/way/27155530) and duration last 2:15 h.  The sun and heat will be softer 
but maybe you'll want to bring some water. If you have really very clear skin consider some protection.
+
+Have in mind this visit ut is not very accessible: it's a castle over a hill!
+
+### Picnic and Flamenco show
+
+![](/images/chinelita/patio-naranjos.jpg){:width="40%" align="right"}
+
+
+After the alcazaba visit we'll walk to the Barracks of the Mercy, a XVIII century building and local 
headquarters of the military. Again we'll walk through the old downtown of Almería, most from the XVI century 
after a set of earthquakes destroyed the old Muslim city, to the picnic place, the  _Patio of the orange 
trees_. There we'll enjoy dinner with a nice view of the Alcazaba under night lighting. 
+
+But this is not all. For the conference big party we'll offer you a __flamenco concert__ with Spanish 
guitar, singer, percussionist and a flamenco dancer. 
+[La Chinelita](https://www.facebook.com/lachinelita.bailaora/) is these days another emergent artist from 
the traditional Almería's flamenco tradition. La Chinelita's combo will steal your heart with the rapt 
passion of the dance at the compass of guitar and the deep lament, the «quejío», singing, threaded with the 
universal soul emotions.
+
+
+![](/images/chinelita/2017-01-26-gala-suerte-cervantes-239.jpg){:width="300"}
+![](/images/chinelita/2017-01-26-gala-suerte-cervantes-312.jpg){:width="300"}
+
+The party starts at __22:00__ at the [Patio de los Naranjos](https://www.openstreetmap.org/node/5732646949) 
and is expected to finish about 01:00.
+
+The availability of the _Patio of the orange trees_ is thanks to the [Ministry of Defense of 
Spain](http://www.defensa.gob.es/). The only condition is to behave under the basic norms of coexistence and 
civics. As we know this is obvious we just should remark it.
+
+Warning: due to the characteristics of the ground the patio's floor is uneven. __Watch your step__.
+
+
+
+
+
+
+
+
diff --git a/content/pages/sponsors.md b/content/pages/sponsors.md
new file mode 100644
index 0000000..0fb12ad
--- /dev/null
+++ b/content/pages/sponsors.md
@@ -0,0 +1,51 @@
+Title: Sponsors
+Date: 20180219
+
+GUADEC could not happen without the support of sponsors. We are immensely
+grateful to the following organisations for their support.
+
+If you are interested in sponsoring this year’s GUADEC, see [how to sponsor](how-to-sponsor.html).
+
+## 2018 Sponsors
+
+### Platinum
+
+&nbsp; | &nbsp;
+     - | -
+![PIA Logo](/images/sponsors/pia.png){: .sponsorlogo } | Private Internet Access (PIA), is the leading 
no-log VPN service provider in the world. PIA believes that access to an open internet is a fundamental human 
right and donates effusively to causes such as EFF, ORG, and FFTF to promote privacy causes internationally. 
PIA has over 3,200 servers in 25 countries that provide reliable, encrypted VPN tunnel gateways for whatever 
the use case. Please visit [their website](https://www.privateinternetaccess.com) for more information.
+
+---
+
+### Gold
+
+&nbsp; | &nbsp;
+     - | -
+![RedHat Logo](/images/sponsors/redhat.png){: .sponsorlogo } | [Red Hat](https://www.redhat.com/) is the 
world’s leading provider of open source software solutions, using a community-powered approach to provide 
reliable and high-performing cloud, Linux, middleware, storage and virtualization technologies. Red Hat also 
offers award-winning support, training, and consulting services. As a connective hub in a global network of 
enterprises, partners, and open source communities, Red Hat helps create relevant, innovative technologies 
that liberate resources for growth and prepare customers for the future of IT.
+    |
+![Endless Logo](/images/sponsors/endless.png){: .sponsorlogo } | [Endless](https://endlessos.com/) was 
founded in 2012 with a single mission: to make computing universally accessible by solving the barriers of 
cost, connectivity, and ease of use. The flagship product is called Endless OS, a fully functional operating 
system designed for emerging markets. Endless is built on the GNOME stack and is intuitive for users who have 
no experience with technology. It works well with extremely poor internet connections and makes use of heavy 
caching to help users access the content they need in areas with little access to internet. It comes with 
over 100 apps so that it’s useful from the moment you turn it on – even if you don’t have an internet 
connection. Endless has created apps packed with valuable content for education, health, wellness, parenting, 
small business, and many other areas to help users achieve the best in life. Endless’ vision is for users to 
be the co-creato
 rs of a 
 vibrant app ecosystem that solves real-life challenges and is building a toolkit to enable everyone, 
regardless of technical expertise, to participate in creating locally relevant content.
+
+---
+
+### Silver
+
+&nbsp; | &nbsp;
+     - | -
+![Canonical Logo](/images/sponsors/canonical.png){: .sponsorlogo } | Established in 2004, Canonical is the 
company behind Ubuntu, a platform that spans from the PC and IoT devices to the server and the cloud. It 
includes a comprehensive suite of enterprise-grade tools for development, configuration, management and 
service orchestration. Ubuntu comes with everything you need to run your organisation, school, home or 
enterprise. Canonical provides enterprise products, support and services for Ubuntu. Canonical is a privately 
held company.
+     |
+![openSUSE Logo](/images/sponsors/opensuse.png){: .sponsorlogo } | The [openSUSE](https://www.opensuse.org/) 
project is a worldwide effort that promotes the use of Linux everywhere. openSUSE creates one of the world’s 
best Linux distributions, working together in an open, transparent and friendly manner as part of the 
worldwide Free and Open Source Software community.The project is controlled by its community and relies on 
the contributions of individuals, working as testers, writers, translators, usability experts, artists and 
ambassadors or developers. The project embraces a wide variety of technology, people with different levels of 
expertise, speaking different languages and having different cultural backgrounds.
+    |
+![Codethink Logo](/images/sponsors/codethink.png){: .sponsorlogo } | 
[Codethink](https://www.codethink.co.uk) specialises in system-level software engineering to enable advanced 
technical applications, working across a range of industries including automotive, medical, telecoms and 
finance. Our customers are international-scale organizations who seek competitive edge through design of 
enterprise appliances and embedded systems which are faster, smaller, more secure, more up-to-date, or more 
advanced than their competitors.As experts in Free and Open Source Software, we help customers take maximum 
advantage of the knowledge and technologies developed in upstream communities including GNOME. Vala, GLib, 
GTK+, Glade, Flatpak, Tracker, and Gstreamer are just a few of the GNOME technologies that Codethink 
developers have hacked on in recent years.
+
+---
+
+### Bronze
+
+&nbsp; | &nbsp;
+     - | -
+![GitLab logo](/images/sponsors/gitlab.png){: .sponsorlogo } | [GitLab](https://gitlab.com) is the first 
single application for all stages of the DevOps lifecycle. Only GitLab enables Concurrent DevOps, unlocking 
organizations from the constraints of today’s toolchain. GitLab provides unmatched visibility, radical new 
levels of efficiency and comprehensive governance to significantly compress the time between planning a 
change and monitoring its effect. This make the software lifecycle 3 times faster, radically improving the 
speed of business.
+      | 
+![Igalia logo](/images/sponsors/igalia.png){: .sponsorlogo } | [Igalia](https://www.igalia.com) is an open 
source consultancy specialized in the development of innovative projects and solutions. Our engineers have 
expertise in a wide range of technological areas, including browsers and client-side web technologies, 
graphics pipeline, compilers and virtual machines. Leading the development of essential projects in the areas 
of web rendering and browsers, we have the most WPE, WebKit, Chromium/Blink and Firefox expertise found in 
the consulting business, including many reviewers and committers. Igalia designs, develops, customises and 
optimises GNU/Linux-based solutions for companies across the globe. Igalia has been involved in GNOME since 
the early days, contributing to the project in many areas, including accessibility support, browsers and web 
engines, or document viewers.
+      | 
+![ARM logo](/images/sponsors/arm.png){: .sponsorlogo } | As the leading semiconductor IP company, 
[ARM](https://www.arm.com) strives to architect a smarter world transforming lives through innovation. ARM IP 
powers a global ecosystem of innovators and is found in almost every facet of life from sensors to servers 
and all points in between.
+
+---
diff --git a/content/pages/submit-a-proposal.md b/content/pages/submit-a-proposal.md
new file mode 100644
index 0000000..255befa
--- /dev/null
+++ b/content/pages/submit-a-proposal.md
@@ -0,0 +1,59 @@
+Title: Submit a proposal
+Date: 20180604
+Authors: Kat, Nuritzi
+
+## Presentations and talks at GUADEC
+
+### Dates to remember
+
+* CFP Notifications: May, 2018
+* Schedule Announcement: June, 2018
+* BoF signup: end of June, 2018
+* Ad hoc session signup: mornings Friday, July 6 – Sunday, July 11, 2018
+* Lightning talk signup: morning Sunday, July 11, 2018
+
+### Scheduled presentations
+The call or proposals is now closed. These will be 25 and 40 minute talks.
+
+
+### BoFs & hackfests
+
+
+Main page at 
[https://wiki.gnome.org/GUADEC/2018/Hacking%20days](https://wiki.gnome.org/GUADEC/2018/Hacking%20days):
+<iframe src="https://wiki.gnome.org/GUADEC/2018/Hacking%20days"; width="100%" height="600" frameborder="0" 
style="border:0" allowfullscreen></iframe>
+
+
+
+### Ad hoc sessions
+There will be *ad hoc* slots available on each of the main conference days
+(6th to 8th July). You will be able to propose sessions for these on the day.
+Attendees will have a chance to vote for them until lunch time and the
+sessions with the highest number of votes will take place at the end of the
+same day. If your proposal is not selected you can resubmit it on a following
+day. Sessions can be on any topic which is suitable for the audience,
+including topics outside of GNOME and software.
+
+### Lightning talks
+Lightning talk slots will be available for signup on the morning of Sunday 8th
+July. Talks can be on any topic which is suitable for the audience. Lightning
+talks are normally 3 minutes long, depending on the length of the available
+slot. Talks will happen in the order that they are listed on the sign up sheet
+and speaker changes will be fast paced, so you need to come to the room 5
+minutes before the lightning talks start and are expected to send in PDFs of
+your slides beforehand. If you want to use your own laptop for a demo or
+because you cannot export your slides in PDF format, any setup will come out of
+your allotted speaking time.
+
+Intern lighting talks are reserved for anyone interning with GNOME. These are
+by invitation only. If you think that you are eligible to present your project
+during this slot, please get in touch with the GSoC admins at GNOME.
+
+### Contact
+
+The papers team is looking forward to your talk proposal. In case of questions
+regarding the call for talks, please contact the papers team at
+[guadec-papers gnome org](mailto:guadec-papers gnome org). For general
+questions regarding the conference, please consult the GUADEC website or
+contact the local GUADEC organizing team at
+[guadec-organization gnome org](mailto:guadec-organization gnome org) (public
+mailing list).
diff --git a/content/pages/talks-and-events.md b/content/pages/talks-and-events.md
new file mode 100644
index 0000000..6fec528
--- /dev/null
+++ b/content/pages/talks-and-events.md
@@ -0,0 +1,18 @@
+Title: Talks and Events
+Date: 20180608
+
+
+
+
+
+
+<!-- AUTOGENERATED --><div><div class="abstract" id="abstract-121-beach_party"><h4><a 
href="/pages/schedule.html#121-beach_party">Beach Party</a></h4><span class="details">On Friday at 20:00 
(Elsewhere) by GUADEC Team</span><p>Details will be announced later.</p></div><div class="abstract" 
id="abstract-26-better_gtk_and_app_development_on_windows"><h4><a 
href="/pages/schedule.html#26-better_gtk_and_app_development_on_windows">Better GTK+ and app development on 
Windows</a></h4><span class="details">On Friday at 13:00 (Auditorium) by Nirbheek Chauhan</span><p>Last year 
at GUADEC, Jussi Pakkanen talked about how the Meson build system's subprojects and wrapdb features enable 
easier app development on all platforms.</p><p>This year I will talk about how these features have matured 
and now allow GTK+ and GTK+ app development on Windows without needing extraneous steps, fragile build 
environments such as MSYS or Cygwin, or non-native toolchains such as MinGW GCC.</p><p>I will demo
 nstrate 
 how easy it now is to develop, debug, and profile your GTK+ apps with the tools that Windows developers 
expect to be able to use.</p></div><div class="abstract" id="abstract-112-unconference-1"><h4><a 
href="/pages/schedule.html#112-unconference-1">Breaking into and defending Linux – examples</a></h4><span 
class="details">On Sunday at 15:00 (Auditorium) by dcz</span><p>Breaking into and defending Linux – 
examples</p></div><div class="abstract" id="abstract-108-unconference-1"><h4><a 
href="/pages/schedule.html#108-unconference-1">Building Flatpak apps with Buildstream</a></h4><span 
class="details">On Saturday at 15:00 (Auditorium) by Sam Thursfield</span><p>Building Flatpak apps with 
Buildstream</p></div><div class="abstract" id="abstract-114-unconference-1"><h4><a 
href="/pages/schedule.html#114-unconference-1">Building for humans: methods for improving 
usability</a></h4><span class="details">On Sunday at 15:30 (Auditorium) by Robin</span><p>Building for 
humans: methods fo
 r improv
 ing usability</p></div><div class="abstract" id="abstract-28-building_the_libre_desktop"><h4><a 
href="/pages/schedule.html#28-building_the_libre_desktop">Building the Libre Desktop</a></h4><span 
class="details">On Saturday at 12:15 (Conference Room) by Louisa Bisio</span><p>System76 talks about their 
new Linux desktop manufactured in Denver, CO. Integrated with Pop!_OS, a Gnome-based distro, this desktop 
features open sourced concepts inside and out. In this talk, we share the struggles of building an open 
desktop and why open computer designs are important for an innovative future. In the end, we prove that you 
don’t have to compromise aesthetics, quality, and performance for freedom.</p></div><div class="abstract" 
id="abstract-122-cultural_show__picnic"><h4><a href="/pages/schedule.html#122-cultural_show__picnic">Cultural 
show &amp; picnic</a></h4><span class="details">On Saturday at 19:30 (Elsewhere) by GUADEC 
Team</span><p>Details will be announced later.</p></div><div
  class="
 abstract" id="abstract-42-dealing_with_controversy__a_practical_guideline"><h4><a 
href="/pages/schedule.html#42-dealing_with_controversy__a_practical_guideline">Dealing with controversy - a 
practical guideline</a></h4><span class="details">On Friday at 11:00 (Conference Room) by Sriram 
Ramkrishna</span><p>GNOME is a pioneer in the desktop and beyond.  Being in the pole position means that we 
invite criticisms in our online world both fair and unfair.</p><p>This talk will focus on how to deal with 
controversies, communicating effectively, and extracting relevant feedback to controversial issues while 
maintaining your sanity</p></div><div class="abstract" 
id="abstract-2-design_of_an_ux_case_iot_integration_in_gnome"><h4><a 
href="/pages/schedule.html#2-design_of_an_ux_case_iot_integration_in_gnome">Design of an UX case: IoT 
integration in GNOME.</a></h4><span class="details">On Sunday at 11:00 (Conference Room) by Claudio Alexander 
Santoro Wunder</span><p>The talk would be abou
 t a mock
 up and current ideas for a new user experience case design, integration of smart homes appliances and 
internet of things middleware in GNOME at a glance. Providing details of how successful could be GNOME the 
first UI for Linux that could integrate with such things like Google Assistant, Alexa, Cortana, IFTTT, or 
appliances like Philips Hue and NeXT. By likely integrating the Google Assistant SDK directly in GNOME, 
making GNOME a more human experienced and native language experienced GUI for the Linux 
Environment.</p></div><div class="abstract" id="abstract-19-designing_gnome_mobile"><h4><a 
href="/pages/schedule.html#19-designing_gnome_mobile">Designing GNOME Mobile</a></h4><span class="details">On 
Sunday at 13:00 (Conference Room) by Tobias Bernard</span><p>Purism's Librem 5 is the first phone built from 
the ground up to respect user freedom and privacy. It will run PureOS, a real GNU/Linux distribution, and use 
GNOME as its user interface. But how is that possible? GNOME d
 oesn't r
 un on phones, does it?</p><p>Well, not quite yet, but at Purism we're working on changing that. In my role 
as designer on the Librem 5 project I'm adapting the design of existing GNOME apps to the phone form factor, 
and designing new apps from scratch. We want as much of this work as possible to go upstream, in order to 
benefit all GNOME users.</p><p>In this presentation I'll show some of the progress we've been making, and 
talk about how to design GNOME apps that work well across different form factors.</p></div><div 
class="abstract" id="abstract-13-devops_for_gnome"><h4><a 
href="/pages/schedule.html#13-devops_for_gnome">DevOps for GNOME</a></h4><span class="details">On Sunday at 
12:15 (Conference Room) by Carlos Soriano</span><p>As you probably might know, GNOME hasn't been the most 
updated in technologies &amp; processes used for the design, development, testing, QA, delivery loop. To be 
honest, we have been quite behind!</p><p>Build fails, not passing tests, contributors
  stuck w
 ith trivial details, each product with different released days, designers and QA in need to build the whole 
stack to try out a minimal UI change… well, we could continue indefinitely. Needless to say this was a huge 
impact in our performance and contributor friendliness, even more in a time where web applications are as 
common.</p><p>Fortunately, things have changed dramatically over the last two years, specially with Flatpak 
for a containerized-alike build and distribution of apps and our move to GitLab and its integrated CI, we are 
able to fully dive into integrating a more DevOps oriented workflow. This effort has become a dream come true 
for GNOME, that we would have never imagined a few years back.</p><p>In this talk I will present and explain 
in details how to use and integrate Flatpak and GitLab together to create the future of the DevOps experience 
for Linux applications development and how we use it at GNOME and what impact is making to our 
organization.</p></div>
 <div cla
 ss="abstract" id="abstract-4-download_management_on_metered_connections"><h4><a 
href="/pages/schedule.html#4-download_management_on_metered_connections">Download management on metered 
connections</a></h4><span class="details">On Sunday at 14:30 (Auditorium) by Philip Withnall</span><p>Endless 
OS is often run on machines where internet connectivity is metered: the user has to pay per unit of bandwidth 
used. Due to the variety of tariffs available, reducing the bandwidth cost of important downloads (such as OS 
updates) to the user is non-trivial. We’ve implemented a scheduling system for downloads to address this. It 
has uses on regular laptops too, allowing downloads to be deferred until you’re back home and not using 
mobile data.</p><p>This talk will provide an introduction to download management and how we see it being used 
in future.</p></div><div class="abstract" id="abstract-113-unconference-1"><h4><a 
href="/pages/schedule.html#113-unconference-1">Endless Code</a></h
 4><span 
 class="details">On Sunday at 15:00 (Conference Room) by Philip Chimento</span><p>Endless Code</p></div><div 
class="abstract" id="abstract-41-flathub__an_app_store_and_build_service_for"><h4><a 
href="/pages/schedule.html#41-flathub__an_app_store_and_build_service_for">Flathub - An app store and build 
service for…</a></h4><span class="details">On Saturday at 11:00 (Auditorium) by Robert McQueen &amp; Jorge 
García</span><p>Talk title (complete): Flathub - An app store and build service for flatpak 
applications</p><p>Since last year's launch, Flathub has become the de facto app store for flatpak 
applications, with hundreds of available apps and thousands of monthly users.</p><p>This talk will provide 
answers to the following questions:<br />- What is Flathub? What does it offer users and developers?<br />- 
How can I publish a new app/theme/runtime/...?<br />- How does Flathub work? What is the infrastructure 
behind it (build service, website...)?<br />- What plans are there f
 or futur
 e development?<br />- How can I contribute to Flathub?</p></div><div class="abstract" 
id="abstract-124-flatpak_workshop"><h4><a href="/pages/schedule.html#124-flatpak_workshop">Flatpak 
workshop</a></h4><span class="details">On Monday at 14:00 (Room 1) by Alexander Larsson</span><p>Available 
spaces: 48 on a first come, first serve basis<br />
+Pre-requisites: laptop with flatpak and flatpak-builder installed<br />
+<br />
+Learn the basics of flatpak package and some tricks and tips for developing with flatpak.  The workshop 
starts with me talking about an hour, and then you can bring your own application to package. David and I 
will help people out and bring up common pain points for discussion. If you're only interested in the talk 
part that is fine too.</p></div><div class="abstract" 
id="abstract-20-freedesktopsdk_the_future_of_linux_runtimes"><h4><a 
href="/pages/schedule.html#20-freedesktopsdk_the_future_of_linux_runtimes">Freedesktop-sdk, the future of 
Linux runtimes</a></h4><span class="details">On Saturday at 10:30 (Auditorium) by Adam Jones, Valentin 
David</span><p>The freedesktop-sdk was originally started as a Flatpak subproject to create a minimum Linux 
baseline. It’s now a separate project hosted on freedesktop.org, and is used as the foundation of GNOME 
releases. The long term goal of the project is to maintain a neutral baseline which can be consumed by 
Flatpak, GNOME, KDE and 
 others.<
 /p><p>This talk will focus on the recent work to upgrade and modernize the sdk. We will discuss what the 
project has done so far, including the benefits of improved automation and converting the format entirely to 
BuildStream (rather than several different metadatas). </p><p>We will also talk about what we are doing next 
and why all of this matters to GNOME.</p></div><div class="abstract" 
id="abstract-5-glib_whats_new_and_whats_next"><h4><a 
href="/pages/schedule.html#5-glib_whats_new_and_whats_next">GLib: What’s new and what’s next?</a></h4><span 
class="details">On Sunday at 13:00 (Auditorium) by Philip Withnall</span><p>A look at recent activity in 
GLib, current development, and plans for the future.</p></div><div class="abstract" 
id="abstract-100-gnome_foundation_agm"><h4><a href="/pages/schedule.html#100-gnome_foundation_agm">GNOME 
Foundation AGM</a></h4><span class="details">On Saturday at 16:30 (Auditorium) by GNOME Board</span><p>The 
annual general meeting of the G
 NOME Fou
 ndation</p></div><div class="abstract" id="abstract-21-gnome_foundation_looking_into_the_future"><h4><a 
href="/pages/schedule.html#21-gnome_foundation_looking_into_the_future">GNOME Foundation: Looking into the 
Future</a></h4><span class="details">On Friday at 12:15 (Conference Room) by Rosanna Yuen</span><p>Exciting 
things are afoot! Come hear the plans for what is to come in the GNOME Foundation.</p></div><div 
class="abstract" id="abstract-32-gtk4_lightning_talks"><h4><a 
href="/pages/schedule.html#32-gtk4_lightning_talks">GTK4 Lightning talks</a></h4><span class="details">On 
Friday at 11:00 (Auditorium) by Benjamin Otte</span><p>The GTK team has been hard at work improving the core 
of the toolkit.</p><p>This talk will present all the internal subsystems that have seen changes in the form 
of lightning talk sized chunks, so that by the end of the talk you know about things such as 
GtkMotionController, GskRenderer, GtkSnapshot, GdkPaintable or GtkMediaStream.</p></div><div cl
 ass="abs
 tract" id="abstract-33-have_you_ever_developed_for_a_gpu"><h4><a 
href="/pages/schedule.html#33-have_you_ever_developed_for_a_gpu">Have you ever developed for a 
GPU?</a></h4><span class="details">On Sunday at 10:30 (Conference Room) by Benjamin Otte</span><p>You have 
probably heard about GPUs and OpenGL and seen the wonders that are possible with them. So has the GTK team. 
But what the GTK team hadn't heard about were the traps and pitfalls you have to carefully navigate around to 
make those wonders happen.</p><p>This talk will present what we learned so that you already have a head start 
when you decide to use the magic of GPUs.</p></div><div class="abstract" 
id="abstract-115-unconference-1"><h4><a href="/pages/schedule.html#115-unconference-1">How I secretly wish 
fonts worked (on GNOME)</a></h4><span class="details">On Sunday at 15:30 (Conference Room) by 
Nate</span><p>How I secretly wish fonts worked (on GNOME)</p></div><div class="abstract" 
id="abstract-107-unconference-1
 "><h4><a
  href="/pages/schedule.html#107-unconference-1">How to handle design critique</a></h4><span 
class="details">On Friday at 15:30 (Conference Room) by Nick Richards and Jakub Steiner</span><p>How to 
handle design critique</p></div><div class="abstract" id="abstract-106-unconference-1"><h4><a 
href="/pages/schedule.html#106-unconference-1">Implementing Phone UIs with GTK+</a></h4><span 
class="details">On Friday at 15:30 (Auditorium) by Adrien Plazas</span><p>Implementing Phone UIs with GTK+: 
Tips and Tricks</p></div><div class="abstract" id="abstract-109-unconference-1"><h4><a 
href="/pages/schedule.html#109-unconference-1">Input methods, wayland, and upstreams</a></h4><span 
class="details">On Saturday at 15:00 (Conference Room) by dcz</span><p>Input methods, wayland, and 
upstreams</p></div><div class="abstract" id="abstract-102-intern_and_newcomer_lightning_talks"><h4><a 
href="/pages/schedule.html#102-intern_and_newcomer_lightning_talks">Intern and newcomer lightning talks</a></h
 4><span 
 class="details">On Friday at 16:30 (Auditorium) by Interns and newcomers</span><p>Lightning talks presented 
by Google Summer of Code and Outreachy interns, and newcomers to GNOME. If you are a newcomer and would like 
to present a lighting talk, please e-mail &lt;a href="mailto:kat gnome org"&gt;Kat&lt;/a&gt;</p></div><div 
class="abstract" id="abstract-30-javascript_in_gnome_in_2018"><h4><a 
href="/pages/schedule.html#30-javascript_in_gnome_in_2018">Javascript in GNOME in 2018</a></h4><span 
class="details">On Saturday at 10:30 (Conference Room) by Philip Chimento</span><p>This talk is about all the 
improvements made in GNOME's Javascript platform in the past year. We've made many strides: developer 
experience, especially for new contributors; new Javascript language features; and performance improvements, 
especially in memory usage. I'll talk about the improvements and how they affect the four audiences: users, 
app developers, GNOME Shell developers, and shell extension develo
 pers. I'
 ll also talk about some projects that we need your help with!</p></div><div class="abstract" 
id="abstract-103-lightning_talks"><h4><a href="/pages/schedule.html#103-lightning_talks">Lightning 
talks</a></h4><span class="details">On Sunday at 16:30 (Auditorium)</span><p>Fast-paced and focused talks on 
any and all subjects. All talks will be subject to a strict time limit of 5 minutes on stage (including 
setup). Slides are welcome, but not compulsory.<br />You will be able to sign up for a lightning talk slot on 
the day. Talks will be accepted on a first come, first serve basis.</p></div><div class="abstract" 
id="abstract-25-making_a_phone_call_with_gnome"><h4><a 
href="/pages/schedule.html#25-making_a_phone_call_with_gnome">Making a phone call with GNOME</a></h4><span 
class="details">On Saturday at 11:00 (Conference Room) by Bob Ham</span><p>The journey toward making GSM 
calls on the upcoming Librem 5 phone using the GNOME platform.  An exploration of the issues encountered, th
 e curren
 t status of our Calls application and discussion of intended future work.</p></div><div class="abstract" 
id="abstract-29-maxwell_embedding_widgets_in_webkit"><h4><a 
href="/pages/schedule.html#29-maxwell_embedding_widgets_in_webkit">Maxwell: embedding widgets in 
WebKit</a></h4><span class="details">On Friday at 14:30 (Conference Room) by Juan Pablo 
Ugarte</span><p>Maxwell is a proof of concept library that extends WebKitWebView to let you embed/pack Gtk 
widgets in it using good old GtkContainer API.</p><p>Inspired by Broadway, Maxwell renders all its children 
in an offscreen window and integrate them into the DOM tree by drawing on a HTML5 canvas element.</p><p>In 
this talk we go trough the juicy part of the implementation details, a few test cases and a real world 
application of the library.</p></div><div class="abstract" 
id="abstract-6-migrating_from_jhbuild_to_buildstream"><h4><a 
href="/pages/schedule.html#6-migrating_from_jhbuild_to_buildstream">Migrating from JHBuild to 
 BuildStr
 eam</a></h4><span class="details">On Saturday at 13:00 (Auditorium) by Michael Catanzaro</span><p>JHBuild 
has served GNOME developers well for over a decade, but it is not very reliable and has caused many problems 
for newcomers attempting to build our software with it. This talk will present BuildStream, a new system for 
reliably building all of GNOME, and compare it to JHBuild. The focus will be on helping developers who are 
already familiar with JHBuild migrate to using BuildStream instead. Advantages and disadvantages of 
BuildStream relative to both JHBuild and flatpak-builder will be discussed.</p><p>This talk will also 
introduce gnome-build-meta, the new official source for GNOME build definitions, which is intended to 
obsolete the JHBuild modulesets, the GNOME Continuous manifest, and the manifest used to build GNOME's 
Flatpak runtimes.</p></div><div class="abstract" id="abstract-44-miracast_for_gnome"><h4><a 
href="/pages/schedule.html#44-miracast_for_gnome">Miracast 
 for GNOM
 E</a></h4><span class="details">On Friday at 14:30 (Auditorium) by Benjamin Berg</span><p>Miracast is a 
standard that allows streaming video and audio content over WiFi connections. This can either work on a local 
network (i.e. when connected to an AccessPoint or Infrastructure network) or through a direct P2P connection 
(WiFi-Direct) to a miracast enabled dongle.</p><p>This talk will give an overview of the progress made so far 
to support such devices on GNOME. While this work builds on miraclecast 
(https://github.com/albfan/miraclecast) a number of improvements throughout stack are required to make these 
devices easily usable to users.</p><p>Note: Most of the work for this talk has not yet happened. I expect 
that at least a number of the core integration issues will be solved by GUADEC and a proof of concept can be 
demonstrated.</p></div><div class="abstract" id="abstract-Open talk"><h4><a href="/pages/schedule.html#Open 
talk">Open talk</a></h4><span class="details">At dif
 ferent t
 imes by to be announced on the day</span><p>You can submit proposals for 20 minute slots for talks, 
discussion panels and presentations in other formats. The presentation with most votes from attendees will be 
selected at 14:20 each day to be presented at 15:00 or 15:30.<br />This is your chance to present cutting 
edge developments or anything that did not make it into the normal schedule.</p></div><div class="abstract" 
id="abstract-40-p2p_distribution_of_flatpaks_and_ostrees"><h4><a 
href="/pages/schedule.html#40-p2p_distribution_of_flatpaks_and_ostrees">P2P Distribution of Flatpaks and 
OSTrees</a></h4><span class="details">On Saturday at 12:15 (Auditorium) by Matthew Leeds</span><p>Endless is 
empowering the world by bringing the computing revolution to the people that have been left out due to the 
barriers of cost and connectivity, and this mission is only made possible by GNOME and other free software. 
One of the ways we're working on making computers useful in conditions 
 of limit
 ed or nonexistent Internet connectivity is by allowing apps and OS updates to be distributed in a P2P way, 
over USB drives and local networks. This feature has required significant changes to both OSTree and Flatpak, 
two of the technologies that underlie Endless OS. We're planning to roll out the feature this summer, and 
this talk will focus on both the technical aspects and the user needs that motivated the work.</p></div><div 
class="abstract" id="abstract-24-patterns_of_refactoring_c_to_rust"><h4><a 
href="/pages/schedule.html#24-patterns_of_refactoring_c_to_rust">Patterns of refactoring C to 
Rust</a></h4><span class="details">On Sunday at 12:15 (Auditorium) by Federico Mena Quintero</span><p>Last 
year I gave a talk on *why* it was desirable to port librsvg from C to Rust.  That talk showed cool things 
about the Rust language, mostly centered around expresiveness and memory safety.</p><p>This time, I want to 
show you *how* the librsvg team (we have a team now!) has been doi
 ng the p
 ort, gradually, steadily, without breaking client applications.  We will present common patterns that show 
up when refactoring C to make it easy to port to Rust.  We'll show how the first pass at Rustification works, 
but it is ugly - but how a second pass can turn it into beautiful, idiomatic Rust code.  We'll show how C 
code with no error handling can be turned into Rust code that checks and propagates errors 
thoroughly.</p><p>The hope is to show that we can give the low-level GNOME platform another 20 years of life 
by porting it to a better low-level language.</p></div><div class="abstract" id="abstract-14-pipewire"><h4><a 
href="/pages/schedule.html#14-pipewire">PipeWire</a></h4><span class="details">On Sunday at 10:30 
(Auditorium) by Wim Taymans</span><p>PipeWire is a modern graph-based multimedia processing engine that aims 
to make it possible to exchange content between applications and devices. It builds on concepts from many 
different sources such as GStreamer, JACK, 
 CoreAudi
 o, Pulseaudio, Wayland and LV2.</p><p>In this talk we will briefly go over the current state of PipeWire. 
The remainder will consist of a demonstration of the audio and video processing capabilities and will show 
how the integration of Desktop and Pro audio can be achieved.</p></div><div class="abstract" 
id="abstract-47-plan_your_testing"><h4><a href="/pages/schedule.html#47-plan_your_testing">Plan your 
testing</a></h4><span class="details">On Saturday at 13:00 (Conference Room) by Kat</span><p>GNOME has seen a 
number of initiatives to improve testing over recent years and the project is in the best position to see 
further improvements. Automated testing, especially with the move to GitLab, is more effective than ever. 
Usability testing has seen a lot of work from Jim Hall and the design team. But what about the planning and 
organisation around delivering GNOME as a product?</p><p>I will discuss the theory and processes around 
planning testing for a product like GNOME with r
 egular r
 eleases, using real life examples from Apertis and how they can be applied to applications and the GNOME 
desktop. I will discuss the pros and cons of different approaches and how to decide what you should be 
using.</p></div><div class="abstract" id="abstract-39-product_management_in_open_source"><h4><a 
href="/pages/schedule.html#39-product_management_in_open_source">Product Management in Open 
Source</a></h4><span class="details">On Friday at 13:00 (Conference Room) by Nick Richards</span><p>What role 
does Product Management and other non coding roles play within open source and GNOME? Inspired by an 
excellent blog post from Christian Hergert this will talk about cherishing and encouraging non coding roles 
within GNOME. I'll cover what Product Management is and how it can help with some of the challenges the 
community is facing.</p></div><div class="abstract" 
id="abstract-10-simple_tricks_to_assess_and_improve_the_security_o"><h4><a 
href="/pages/schedule.html#10-simple_tricks
 _to_asse
 ss_and_improve_the_security_o">Simple tricks to assess and improve the security o</a></h4><span 
class="details">On Sunday at 14:30 (Conference Room) by T̛̮ò̗b͎̈́i̧͐a̠̐s͓̒ 
̘̂M̧͋ṳ͂e̞͠ĺ̩l̟̍é̩r̛͉</span><p>We have powerful tools such as Address Sanitizer and american fuzzy lop at 
our disposal. Together with the reproducible build in clean environments that flatpak provide, we can shake 
bugs out of our apps as easily and efficiently as never before.  In this talk, I will demonstrate how to 
build an app such that the potential of the security related tools is maximised, how to interpret results, 
and ways forward to improve the security of all (self compiled) flatpak apps and thus the wider ecosystem, 
hoping to make GNOME a leader in the field of secure app delivery.</p></div><div class="abstract" 
id="abstract-110-unconference-1"><h4><a href="/pages/schedule.html#110-unconference-1">Slimbook Linux 
laptops</a></h4><span class="details">On Saturday at 15
 :30 (Aud
 itorium) by Slimbook</span><p>Slimbook Linux laptops</p></div><div class="abstract" 
id="abstract-111-unconference-1"><h4><a href="/pages/schedule.html#111-unconference-1">Snap Package support 
in GNOME</a></h4><span class="details">On Saturday at 15:30 (Conference Room) by Robert Ancell</span><p>Snap 
Package support in GNOME</p></div><div class="abstract" 
id="abstract-34-the_infamous_gnome_shell_performance"><h4><a 
href="/pages/schedule.html#34-the_infamous_gnome_shell_performance">The infamous GNOME Shell 
performance</a></h4><span class="details">On Friday at 12:15 (Auditorium) by Jonas Ådahl, Carlos 
Garnacho</span><p>Over the past year, there has been lots of things going on related to GNOME Shells 
performance and memory consumption, including a hackfest in Cambridge, UK, in the middle of May. This talk 
aims to summarize what has happened lately within these topics, and what will happen in the 
future.</p></div><div class="abstract" id="abstract-16-thunderbolt_gnulinux_and_
 gnome"><
 h4><a href="/pages/schedule.html#16-thunderbolt_gnulinux_and_gnome">Thunderbolt, GNU/Linux and 
GNOME</a></h4><span class="details">On Saturday at 14:30 (Auditorium) by Christian 
Kellner</span><p>Thunderbolt 3 is a relatively new technology to connect peripherals to a computer. Because 
it can access the computer's resources directly, it allows for very high speeds: it is fast enough to drive 
external graphics cards.<br />However, the mechanism that allows these high speeds also poses a security risk 
because malicious devices could obtain sensitive information from the computer's memory.<br />Version 3 of 
the Thunderbolt interface therefore provides security levels in order to mitigate the aforementioned security 
risk that connected devices pose to the system. As a result, devices need to be authorized manually. The talk 
aims to provide an overview of the Thunderbolt technology and will try to clarify some of the confusing 
aspects, e.g. the many modes and features of the USB t
 ype C co
 nnector that Thunderbolt 3 uses. Finally, the talk will show how some tricky user experience problems were 
solved, with a focus on the integration with GNOME.</p></div><div class="abstract" 
id="abstract-3-translating_software_using_related_languages"><h4><a 
href="/pages/schedule.html#3-translating_software_using_related_languages">Translating software using related 
languages</a></h4><span class="details">On Saturday at 14:30 (Conference Room) by Rūdolfs 
Mazurs</span><p>Intended audience: translators, current and aspiring l10n team leaders</p><p>Summary:<br 
/>Translating a big software project like GNOME is hard, especially for small teams. However, if the target 
language is related to another language that already has good coverage, the translation can be done much 
faster. In this talk I will explain the word substitution translation method and the new tool that implements 
it for GNOME translation files, mt-words.</p><p>Talk overview:<br />- Currently available tools for so
 ftware t
 ranslators<br />- Machine translation approaches used in general<br />- Detailed overview of the 
word-substitution method,<br />  including its strengths and which languages could use it<br />- What makes 
software interfaces easier and harder to translate<br />- Why word substitution translation is suitable for 
GNOME<br />- Presenting my translation script “mt-words”, an overview of how <br />  it addresses the issues 
with translating .po files<br />- Case study: translating parts of GNOME from Latvian to Latgalian<br />  * 
preparing the source language text<br />  * writing the translation script<br />  * creating the dictionary 
and terminology<br />  * editing the final translation<br />- Overview of how to maintain translations; what 
to do if:<br />  * the original English string changes<br />  * the related language string changes<br />  * 
a dictionary record changes</p></div><div class="abstract" 
id="abstract-50-ubuntus_journey_from_unity_to_gnome_shell"><h4><a href
 ="/pages
 /schedule.html#50-ubuntus_journey_from_unity_to_gnome_shell">Ubuntu's journey from Unity to GNOME 
Shell</a></h4><span class="details">On Friday at 10:30 (Auditorium) by Ken VanDine, Didier 
Roche</span><p>Since 2011, Ubuntu had shipped Unity as the default shell for Ubuntu.  In 2017 the decision 
was made to transition from Unity to GNOME Shell as the default experience for Ubuntu.  We made the 
transition and shipped GNOME Shell by default in 17.10, with a slightly modified default experience.  We've 
since shipped GNOME Shell by default in 18.04, our latest LTS release.  </p><p>We'll talk about how we 
tackled this transition, obstacles we encountered and how we dealt with them.  We'll also present current 
challenges and what we hope will be a solid path forward.</p></div><div class="abstract" 
id="abstract-15-whats_happening_in_builder"><h4><a 
href="/pages/schedule.html#15-whats_happening_in_builder">What's happening in Builder?</a></h4><span 
class="details">On Sunday at 11:00 
 (Auditor
 ium) by Christian Hergert, Corentin Noël</span><p>This year we'll discuss what has and hasn't been working 
well in Builder and what we're doing to address it.</p><p>As usual, there will be plenty of demos and tips 
for how to use Builder more efficiently.</p><p>Lastly, an overview of various plugin API will be provided to 
help GNOME contributors join in improving our tooling.</p></div></div><!-- /AUTOGENERATED -->
+
+
+
+
+
+
diff --git a/content/pages/test-map.md b/content/pages/test-map.md
new file mode 100644
index 0000000..11837b7
--- /dev/null
+++ b/content/pages/test-map.md
@@ -0,0 +1,37 @@
+Title: Test map
+Date: 20180219
+
+## OSM Map test with leaflet
+
+<div id="map" style="width: 100%; height: 600px;"></div>
+
+<script>
+
+       var planes = [
+               ["7C6B07",-40.99497,174.50808],
+               ["7C6B38",-41.30269,173.63696],
+               ["7C6CA1",-41.49413,173.5421],
+               ["7C6CA2",-40.98585,174.50659],
+               ["C81D9D",-40.93163,173.81726],
+               ["C82009",-41.5183,174.78081],
+               ["C82081",-41.42079,173.5783],
+               ["C820AB",-42.08414,173.96632],
+               ["C820B6",-41.51285,173.53274]
+               ];
+
+        var map = L.map('map').setView([-41.3058, 174.82082], 8);
+        mapLink = 
+            '<a href="http://openstreetmap.org";>OpenStreetMap</a>';
+        L.tileLayer(
+            'http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+            attribution: '&copy; ' + mapLink + ' Contributors',
+            maxZoom: 18,
+            }).addTo(map);
+
+               for (var i = 0; i < planes.length; i++) {
+                       marker = new L.marker([planes[i][1],planes[i][2]])
+                               .bindPopup(planes[i][0])
+                               .addTo(map);
+               }
+               
+</script>
\ No newline at end of file
diff --git a/content/pages/tourism.md b/content/pages/tourism.md
new file mode 100644
index 0000000..c6413b4
--- /dev/null
+++ b/content/pages/tourism.md
@@ -0,0 +1,132 @@
+Title: Tourism in Almería
+Date: 20180605
+
+![Monsul 
Beach](https://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/Küste_bei_Monsul14.jpg/800px-Küste_bei_Monsul14.jpg){:width="300"
 align="right"}
+
+The province landscapes are extraordinaire. You can find three or more
+different climates/ecosystems in an hour travel car.
+
+Usually our visitants fall in love with the [Cabo de Gata-Níjar Natural 
Park](https://en.wikipedia.org/wiki/Cabo_de_Gata-N%C3%ADjar_Natural_Park),
+a sea and land protected space said to be one of the best places in
+Spain to dive.
+
+When in Almería you can take the opportunity to spend a few days resting
+here. But be sure to do your reservations soon enough since is tourist
+high season.
+
+
+Since probably it will be the first time you'll visit Almería and theses
+parts of Spain we feel you could take the opportunity to travel with
+your family.
+
+![Arabic Well](https://upload.wikimedia.org/wikipedia/commons/b/be/Well_\(9599702769\).jpg){:width="300" 
align="right"}
+
+So they can have a parallel set of activities of active
+tourism both in the city or in any of the beautiful landscapes,
+specially the [Cabo de Gata-Níjar Natural 
Park](https://en.wikipedia.org/wiki/Cabo_de_Gata-N%C3%ADjar_Natural_Park).
+Indeed you could want to spent holidays time after GUADEC with your
+significant ones. An you'll find a lot of [companies offering outdoors 
activities](https://www.turismodealmeria.org/en/what-to-do/experiences/):
+
+
+
+-   tracking routes, both in park and other places in the province
+-   bus guided visits to beautiful places, both in park and other places
+    in the province
+-   horse riding
+-   snorkeling in the natural park waters
+-   scuba diving baptisms in the natural park waters
+-   kayak routes in the natural park waters
+
+![Almeria's 
Alcazaba](https://3.bp.blogspot.com/-h3Ia78wSNTA/U5yhrgOhFsI/AAAAAAAAAEE/to1euw6q7yQ/s400/Alcazaba_de_Almería.jpg){:width="300"
 align="right"}
+
+
+The [city of Almería has its own 
offers](https://www.turismodealmeria.org/en/travel-preparations/culture-and-traditions/):
+
+
+-   [The Alcazaba moorish castle](https://en.wikipedia.org/wiki/Alcazaba_of_Almer%C3%ADa)
+    about 1000 years old
+- [The Museum of Almería](https://en.wikipedia.org/wiki/Museum_of_Almer%C3%ADa)
+-   a beautiful XIX bourgeois downtown
+-   and the restored [air raid shelters](https://en.wikipedia.org/wiki/Almer%C3%ADa_air_raid_shelters)
+    build in the Spanish Civil War
+- and a lot of others [historic places and 
museums](https://www.turismodealmeria.org/en/travel-preparations/culture-and-traditions/#museums-and-exhibition-certres)
 to visit.
+
+There is an [Almería Tourist Guide 
application](https://play.google.com/store/apps/details?id=com.segittur.almeria) for Android.
+
+Very near the city (less than 30 Km far):
+
+![Recreation of Los 
Millares](https://upload.wikimedia.org/wikipedia/commons/thumb/1/1c/Los_Millares_recreacion_cuadro.jpg/290px-Los_Millares_recreacion_cuadro.jpg){:width="300"
 align="right"}
+
+-   visit to the [Los Millares Calcolithic archaeological site](https://en.wikipedia.org/wiki/Los_Millares), 
five
+    thousand years old, one of the most important of the world for that
+    age;
+-   attend to the [recreation and espectable of Western movies](http://fortbravooficial.com/) in real cinema 
stages
+    used in world famous Spaguetti Western movies, like Sergio Leone and
+    Clint Eastwood ones or TV shows like Dr. Who;
+-   visit to the international research place [Almería Solar 
Platform](https://en.wikipedia.org/wiki/Plataforma_Solar_de_Almer%C3%ADa);
+-   visit to the [German-Spanish Astronomical Centre of Calar 
Alto](http://www.azimuthspain.com/en/calar-alto/).
+
+
+A bit more far there are some nice destinations:
+
+-   the [Alpujarras](https://en.wikipedia.org/wiki/Alpujarras)
+    zone has great places with exotic landscapes and towns with ancient
+    origins, Moorish and sooner indeed;
+-   The marvellous [city of Granada](https://en.wikipedia.org/wiki/Granada) and province
+    is less than two hour by car. Remember there is the
+    [Alhambra](https://wiki.gnome.org/Alhambra), a World Heritage place
+    [Washington Irving](https://en.wikipedia.org/wiki/Washington_Irving)
+    felt in love and which inspired his famous [Tales of the 
Alhambra](https://en.wikipedia.org/wiki/Tales_of_the_Alhambra).
+-   and the first nudism hotel in Europa at the [4 stars Vera Playa Club 
Hotel](https://www.playasenator.com/hoteles/vera-playa-club-hotel/),
+    if you like
+    ![:)](https://wiki.gnome.org/gnome/gnome-responsive/img/smile.png ":)")
+-   [Málaga city](https://en.wikipedia.org/wiki/M%C3%A1laga) and
+    province, a popular place for sun and beach tourism and a nice
+    places like the [white towns](https://en.wikipedia.org/wiki/White_Towns_of_Andalusia).
+
+## W̶h̶e̶r̶e̶ How to eat in Almería
+
+![Spanish typical 
tapas](https://www.colourbox.de/preview/2845494-typical-spanish-tapas-prawns-fried-with-oil-and-garlic-served-in-clay-cooking-pot.jpg){:width="300"
 align="right"}
+
+Well, as you can imagine we have restaurants and other meal shops here,
+but what we really love is [to go for
+«tapas»](https://www.turismodealmeria.org/en/what-to-do/gastronomy/)
+![:-)](https://wiki.gnome.org/gnome/gnome-responsive/img/smile.png ":-)")
+
+Almería locals and visitors love to eat tapas. When meeting to eat with friends we tipically go to one or 
several bars and eat several tapas. In Almería each tapa includes a beverage (usually wine, beer or grape 
juice) and an appetizer. Obviously you can drink any other beverage but it's not included in the standard 
price. Do you can have a full lunch with tapas? Yes, sure. The rule of thumb is you can have a meal with 
three tapas. Going for tapas is specially popular for dinner.
+
+So, remember, the ideal way to have your dinner in Almería is going to tapas and as reference you can use 
these _routes of tapas_:
+
+- 
[http://www.andalucia.org/es/eventos/ruta-de-tapas-por-almeria/](http://www.andalucia.org/es/eventos/ruta-de-tapas-por-almeria/)
+- [http://www.weeky.es/xi-ruta-de-tapas-almeria-2018/](http://www.weeky.es/xi-ruta-de-tapas-almeria-2018/)
+- 
[https://www.guiarepsol.com/es/comer/de-tapeo/ruta-de-tapas-por-almeria/](https://www.guiarepsol.com/es/comer/de-tapeo/ruta-de-tapas-por-almeria/)
+
+
+![Western town](https://www.cabogataalmeria.com/img/ocio/th_pobladoOeste2.jpg){:width="300" align="right"}
+
+## More touristic information
+
+You can get more information on
+
+-   [Almería City Turism](http://www.turismodealmeria.org/en/)
+-   [Andalucia.com](http://www.andalucia.com/cities/almeria.htm)
+-   [Municipal Tourist Office of Almería](http://www.andalucia.org/en/contact-us/almeria/almeria-3/)
+
+You can follow other tourist news on:
+
+-   Twitter: [@almerialovers](https://twitter.com/almerialovers)
+-   Instagram: [@almerialovers](https://www.instagram.com/almerialovers/)
+-   Youtube: [turismoalmeria
+    channel](https://www.youtube.com/c/turismoalmeria)
+
+
+## Picture galleries
+
+-   [Almería pictures](https://wiki.gnome.org/IsmaelOlea/GUADEC-2018-Almeria-Bid-pictures)
+-   [Artistic pictures of Almería published in
+    Flickr](https://wiki.gnome.org/IsmaelOlea/GUADEC-2018-Almeria-Bid-Flickr-pictures)
+-   [Flickr Album](https://www.flickr.com/photos/franfazer/albums/72157624101393411)
+    of Almería province from Francisco Javier Requena
+- [beautiful pictures of 
tapas](https://wiki.gnome.org/IsmaelOlea/GUADEC-2018-Almeria-Bid-social#Tapas_route).
+
+![Beaches of 
Almeria](https://3.bp.blogspot.com/-NPP81M_NCfE/UBcTdBzVhBI/AAAAAAAADCM/7lYVNXp_6Rw/s1600/Almeria+playas.jpg){:width="100%"}
diff --git a/content/pages/travel.md b/content/pages/travel.md
new file mode 100644
index 0000000..5c1e53c
--- /dev/null
+++ b/content/pages/travel.md
@@ -0,0 +1,150 @@
+Title: Travel
+Date: 20180321
+
+## Getting there
+
+### Flying to  Almería Airport (LEI)
+
+![Almería 
Airport](https://upload.wikimedia.org/wikipedia/commons/thumb/9/9e/Aeropuerto_de_Almer%C3%ADa.jpeg/320px-Aeropuerto_de_Almer%C3%ADa.jpeg){:align="right"
 width="200"}
+
+[Almería Airport](http://www.aena.es/en/almeria-airport/index.html) has frequent connections to Madrid 
(Iberia) and almost daily
+ones to Barcelona (Vueling). It also has flights to other European airports
+such as London–Gatwick, Amsterdam, Brussels, etc.
+
+At their website you can [check all destinations](http://www.aena.es/en/almeria-airport/destinations.html) 
and [airlines](http://www.aena.es/en/almeria-airport/airlines.html).
+
+Some considerations: in Summer season there are many __direct connections to several European cities__, 
specially by low cost companies. To plan your travel we suggest to check those alternatives since could save 
you a significant amount of money or time. Please double check the airport  
[destinations](http://www.aena.es/en/almeria-airport/destinations.html) and 
[airlines](http://www.aena.es/en/almeria-airport/airlines.html).
+
+
+[Airport is located](https://www.openstreetmap.org/way/37923960) at 9 Km from the city and about 5 minute by 
car from the university campus.
+
+Once you are at the airport you can go to the city:
+
+By bus:
+
+![Surbus Gregorio 
Mara](https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG/320px-L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG){:align="right"
 width="200"}
+
+1. The bus stop at the airport is the #188 (you can check the [wait 
time](http://m.surbus.com/tiempo-espera/parada/188)).
+1. You need [to take Line 30](http://www.surbus.com/inicio.aspx?cat=0&id=30) (1,05 €).
+1. Line 30 connects the city, the airport and the suburbs of Retamar (end of line). Since the bus stop is 
the same in both directions asks bus driver it's going back to the city. If not, you can choose either get 
the bus and pay again at end of line or wait till the bus take the route back from the suburbs.
+1. Get off at "Estación Intermodal", bus stop #292 (you can [check the wait 
time](http://m.surbus.com/tiempo-espera/parada/292)). This is just [outside the bus and train 
station](https://commons.wikimedia.org/wiki/Category:Almer%C3%ADa_train_station#/media/File:Antigua_estaci%C3%B3n_de_ferrocarril_de_Almer%C3%ADa.JPG).
+
+Or by taxi, you can use the PideTaxi application:
+
+- [web app](https://pidetaxi.es/book_taxi)
+- [smartphone app](https://pidetaxi.es/apps)
+
+Or phone / Telegram Whatsapp at: +34667226122
+
+price:
+
+  * Estimated price from airport to city center (or CIVITAS): 20€
+  * Estimated price from airport to university campus: 15€
+
+
+### Flying to Málaga Airport (AGP)
+
+[Málaga airport](http://www.aena.es/en/malaga-airport/index.html) is the fourth busiest in Spain and thus 
has flights to most of
+major European airports and some non-European ones (Montreal, New York,
+Casablanca, Tel Aviv).
+
+You can check [destinations](http://www.aena.es/en/malaga-airport/airport-destinations.html) and 
[airlines](http://www.aena.es/en/malaga-airport/airlines.html).
+
+From Málaga Airport to Almería:
+
+![Ticket at ALSA web](/images/alsa-ticket.png){:width="300px" align="right"}
+
+
+* Direct bus: there's two daily direct buses operated by ALSA, a non stop one that takes around 3h and one 
with two stops that takes 3.5 hours. Probably the best option from Málaga to Almería.
+    * Price: Around 20€ one way
+    * Málaga Airport - Almería: 14:15 and 15:30
+    * Almería - Málaga Airport: 9:30 and 15:30
+    * You can get a ticket by using the [ALSA web page](https://www.alsa.es/) and filling in Almeria as 
destination.
+
+
+* By bus through Málaga:  there's a bus service available that links Málaga Airport with Málaga, and it 
stops both at the main bus station and train station of Málaga.
+  There are a few others daily ALSA buses from Málaga to Almería, taking between 3 and 5 hours depending on 
the intermediate stops. You can buy your tickets at the [ALSA website](https://www.alsa.es/).
+
+In any case your stop in Almería is the [Estación intermodal](https://www.openstreetmap.org/way/27152911) 
which is 10 minutes walking from Civitas residence. There is a taxi stop at the Intermodal too.
+
+<br/>
+
+- Hiring a car: check the [hiring car services at the Málaga 
airport](http://www.aena.es/en/malaga-airport/car-rental.html).
+
+
+![Car-pooling](https://c2.staticflickr.com/4/3203/2329053361_bb54009765_n.jpg){:align="right" width="200px"}
+
+- Do you want to share with other GUADEquenses your hired car ride? Add yourself to the [car sharing 
page](https://wiki.gnome.org/GUADEC/2018/MalagaCarSharing) at GNOME wiki.
+
+* Car-pooling: there are several people that offer car pool rides between different points of Málaga (some 
including the airport) to Almería. [BlaBlaCar](https://www.blablacar.es/) is one of the companies that offers 
such a service.
+
+* By taxi: this may sound crazy, but there are several companies offering transfer between the Málaga 
Airport and Almería ([185€](http://malagaradiotaxi.es/tarifas.html), 
[220€](http://www.taxis-malaga.net/precios.php)) so if you pool with 4 people, it is not that expensive and 
travel time is around 2 hours.
+
+### By road
+
+![A-7 Road](https://upload.wikimedia.org/wikipedia/commons/1/15/Mapa_A-7.png){:align="right" width="200"}
+
+Almería has a good land communication with all the Mediterranean coast by the [A-7 
highway](https://en.wikipedia.org/wiki/Autov%C3%ADa_A-7), which join up to France frontier in La Jonquera 
and, on the other side, ends at Algeciras.
+
+With Spanish interior zones, Almería is connected by the 
[A-92](https://en.wikipedia.org/wiki/Autov%C3%ADa_A-92), another highway that connects with the rest of 
Andalusia and Madrid, Spain capital.
+
+### By train
+
+![Almería Old Train 
Station](https://upload.wikimedia.org/wikipedia/commons/thumb/b/bc/Antigua_estaci%C3%B3n_de_ferrocarril_de_Almer%C3%ADa.JPG/640px-Antigua_estaci%C3%B3n_de_ferrocarril_de_Almer%C3%ADa.JPG){:width="200px"
 align="right"}
+
+There are some lines that connect Almería with Madrid and other cities, such as Granada, Seville, Linares 
and Antequera. The most important option by train is from Madrid. Keep in mind train travel Madrid-Almería 
takes no less than 6 hours.
+
+More information at [Renfe rail transport company](http://www.renfe.com/EN/viajeros/index.html) website.
+
+
+### By ship
+
+There are [some ship lines](http://www.apalmeria.com/index.php?option=com_content&id=95) that connect 
Almería with  Africa: Melilla, Oran (Algeria) and Nador (Morocco) with daily or regular ships and affordable 
prices. The passangers terminal is in the seaside of the city, less than 1 km from downtown.
+
+
+### Mobile/cell phone in Spain
+
+You'll find the city of Almería covered with 4G/3G connectivity. If you have doubts about frequencies and 
compatibilities you can [check this report](https://wiki.bandaancha.st/Frecuencias_telefon%C3%ADa_m%C3%B3vil) 
(in Spanish, sorry).
+
+If you own a cell phone line adquired inside the [European Economic 
Area](https://en.wikipedia.org/wiki/European_Economic_Area) then you'll enjoy [free 
roaming](https://en.wikipedia.org/wiki/European_Union_roaming_regulations#Territorial_extent).
+
+If you want to buy a pre-paid Spanish cell line there options starting from 5€. You'll be required by law to 
identify yourself with a legal document (passport, i.e.) when buying a cell line in Spain.
+
+### Electric plugs
+
+Probably you'll need some electricity, we guess. You can learn about details of the [electric plug system in 
Spain](https://en.wikipedia.org/wiki/Mains_electricity_by_country#Table_of_mains_voltages,_frequencies,_and_plugs).
 In sort: 230 V and 50 Hz.
+
+Plug types:
+
+<div class="text-center">
+    <table>
+        <thead>
+            <th scope="col"><a 
href="https://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7/16_Alternative_II_%22Europlug%22_(Type_C)"
 target="_blank">Type C</a></th>
+            <th scope="col"><a 
href="https://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7/3_socket_and_CEE_7/4_plug_(German_%22Schuko%22;_Type_F)"
 target="_blank">Type F</a></th>
+        </thead>
+        <tbody>
+            <td>
+                <a 
href="https://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7/16_Alternative_II_%22Europlug%22_(Type_C)"target="_blank">
+                    <img 
src="https://upload.wikimedia.org/wikipedia/commons/thumb/6/63/Euro-Flachstecker_2.jpg/330px-Euro-Flachstecker_2.jpg";
 width="200px" alt="Europlug Type C">
+                </a>
+            </td>
+            <td>
+                <a 
href="https://en.wikipedia.org/wiki/AC_power_plugs_and_sockets#CEE_7/3_socket_and_CEE_7/4_plug_(German_%22Schuko%22;_Type_F)"
 target="_blank">
+                    <img 
src="https://upload.wikimedia.org/wikipedia/commons/thumb/e/ef/Schuko_plug_and_socket.png/330px-Schuko_plug_and_socket.png";
 width="200px" alt="Europlug Type F" >
+                </a>
+            </td>
+        </tbody>
+    </table>
+</div>
+
+### Visas
+Check the dedicated page about how to [get a visa to visit Spain](/pages/getting-an-spanish-visa.html).
+
+### Weather
+
+The expected weather is hot. Consider hot summer clothes. Fortunately the venue and residence has 
conditioned air so you'll don't suffer. If you have clear skin consider seriously carry 
[sunscreen](https://www.youtube.com/watch?v=xkgbWGBmgN8) and maybe to wear a cap. It's good idea to keep 
hydrated. At the conference we'll provide fresh water machines.
+
+The probability of rain those days is almost zero. You can check the weather prediction at the [National 
Meteorological Agency](http://www.aemet.es/en/eltiempo/prediccion/municipios/almeria-id04013).
+
+
+Bring swimsuit ;-)
diff --git a/content/pages/unconference.md b/content/pages/unconference.md
new file mode 100644
index 0000000..d33a7a4
--- /dev/null
+++ b/content/pages/unconference.md
@@ -0,0 +1,6 @@
+Title: Unconference
+Date: 20180219
+
+## This content is still in development
+
+We are working to give you the information you want as soon as possible. Please check this page again after 
some days.
diff --git a/content/pages/venue.md b/content/pages/venue.md
new file mode 100644
index 0000000..acbc2b9
--- /dev/null
+++ b/content/pages/venue.md
@@ -0,0 +1,191 @@
+Title: Venue
+Date: 20180219
+
+
+## WiFi connection
+
+The information for WiFi connection follows:
+
+* SSID: GUADEC2018
+* Password: GUADEC2018
+
+![University of Almería](https://i.ytimg.com/vi/MUbXnejv4Bg/hq720.jpg){:width="100%"}
+
+GUADEC 2018 will held at the [University of Almería](https://ual.es/en/) campus. You can check the campus 
localization at [OpenStreetMap](https://www.openstreetmap.org/way/29220363) or [Google 
Maps](https://www.google.es/maps/place/University+of+Almeria/@36.8217122,-2.405678,548a,35y,359.71h,55.4t/data=!3m1!1e3!4m5!3m4!1s0x0:0x2a59668c430f3ff3!8m2!3d36.8293223!4d-2.4044609).
+
+You can explore the campus through this [360º virtual visit](https://w3.ual.es/visitavirtual/).
+
+![The University of Almería from the seaside](/images/UAL-from-sea-_MG_6831.jpg){:width="200px" 
align="right"}
+
+### The university
+
+Currently, UAL has 11.000 students, a 900 teachers staff, and offers [31 official 
careers](https://www.ual.es/en/estudios).
+
+It is a fairly new university, founded in 1993 so you can congratulate us in our [25 
Anniversary](http://www.25ual.es/). It is almost completely hosted in one campus placed at about 6 Km from 
Almería city, just a few meters from the sea, literally.
+
+You can check the [UAL campus 
map](http://cms.ual.es/idc/groups/public/@serv/@infraestructura/documents/actividad/planodelcampus.pdf).
+
+![University of Almería Campus](http://alumnius.net/univer_photos/12206.jpg){:width="100%"}
+
+<a name="direct-bus"></a>
+
+### Communications
+
+#### GUADEC direct bus
+
+![Surbus Gregorio 
Mara](https://upload.wikimedia.org/wikipedia/commons/thumb/0/02/L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG/320px-L30_surbus_Gregorio_Mara%C3%B1%C3%B3n.JPG){:width="200px"
 align="right"}
+
+The campus of the University of Almería is outside the city. There are regular lines everyday but weekends 
schedule is not well fitted for GUADEC. For this reason we charter a direct bus from city and Civitas, the 
planned  GUADEC's main residence, to the university campus. For __core days__ we have bus to go and come from 
campus. For the __BoF days__ we'll have just the morning going to campus for our convenience. To go back to 
the city you could take some of the regular buses.
+
+This is the schedule of the GUADEC direct bus:
+
+* Fri 6th, city → campus
+    * 09:00 departure from [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 09:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+* Fri 6th, city ← campus
+    * 17:50 departure from [university campus](https://www.openstreetmap.org/node/974730957) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 18:15 bus leaves [bus stop 292](https://www.openstreetmap.org/node/2870058034)
+* Sat 7th, city → campus 
+    * 10:00 departure from   [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 10:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+* Sat 7th, city ← campus
+    * 18:40 departure from [university campus](https://www.openstreetmap.org/node/974730957) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 19:05 bus leaves to the [Alcazaba's castle cultural visit](/pages/social-events.html@culture-show")
+* Sun 8th, city → campus
+    * 10:00 departure from   [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 10:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+* Sun 8th, city ← campus
+    * 18:15 departure from [university campus](https://www.openstreetmap.org/node/974730957) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 18:40 bus leaves [bus stop 292](https://www.openstreetmap.org/node/2870058034)
+* Mon 8th, city → campus
+    * 10:00 departure from   [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 10:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+* Tue 10th, city → campus
+    * 10:00 departure from   [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 10:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+* Wed 11th, city → campus
+    * 10:00 departure from   [bus stop 292](https://www.openstreetmap.org/node/2870058034) to 
[CIVITAS](https://www.openstreetmap.org/way/435775764)
+    * 10:10 bus leaves [CIVITAS](https://www.openstreetmap.org/way/435775764) to [university 
campus](https://www.openstreetmap.org/node/974730957)
+
+#### Regular bus
+
+Several regular bus lines connect the city with the campus. Depending from/to which part of the city you 
travel you'll need a different line. In doubt please ask the organization team.
+
+You should know:
+
+- [Line 18](http://m.surbus.com/lineas/linea/18) operates every day of the week
+- [Line 12](http://m.surbus.com/lineas/linea/12) stops at campus just on workdays
+- [Line 11](http://m.surbus.com/lineas/linea/11) stops at campus just on workdays
+
+You can check the waiting time for each bus at [the precise bus 
stop](http://m.surbus.com/tiempo-espera/paradas).
+
+For working days:
+
+- When going from CIVITAS to campus you'll probably would like to take __L12__ bus at [bus stop 
71](https://www.openstreetmap.org/node/469474253) ( [check waiting 
time](http://m.surbus.com/tiempo-espera/parada/71)).
+- When back to CIVITAS from campus you'll want to take the __L11__ bus and get down at [bus stop 
56](https://www.openstreetmap.org/node/469474241) ([check waiting 
time](http://m.surbus.com/tiempo-espera/parada/56)).
+- For going and coming from the campus it's the same [bus stop 
144](https://www.openstreetmap.org/node/974730957) ([check waiting 
times](http://m.surbus.com/tiempo-espera/parada/144)).
+
+#### Taxi
+
+A taxi ride from the city to campus costs about 6 €. You can ask one at the [Pidetaxi web 
application](https://pidetaxi.es/book_taxi). To go to campus just ask driver to go to the main entrance of 
the university.
+
+You can ask for a taxi using Whatsapp or Telegram using in English at +34667226122 [More 
info](http://www.radiotaxialmeria.com/peticion-de-taxi-950-22-22-22/).
+
+#### Bike
+
+There are a bike track from the city to the campus. At the campus you'll find bike lockers. Bring your own 
padlock. Do you want to hire a bike for GUADEC? Please [check this 
information](https://wiki.gnome.org/GUADEC/2018/BikeHiring) and ask organization.
+
+#### Car
+
+It's plenty of parking space too. We recommend [the one just at the main 
entrance](https://www.openstreetmap.org/way/36406072).
+
+![UAL campus air view](/images/ual21-aerea.jpg){:width="100%"}
+
+### GUADEC places
+
+<div class="table-responsive">
+    <table class="table schedule">
+        <tbody>
+            <tr>
+                <td>
+                    <img src="/images/auditorium.jpg" alt="Auditorium" width="300px">
+                </td>
+                <td class="text-left">
+                    <a href="https://www.openstreetmap.org/way/37639082";> Auditorium</a><br/>
+                    <ul>
+                        <li>Core days</li>
+                    </ul>
+                </td>
+            </tr>
+            <tr>
+                <td>
+                    <img src="/images/640px-Universidad_almeria.jpg" alt="Humanidades C Building" 
width="300px">
+                </td>
+                <td class="text-left">
+                    <a href="https://www.openstreetmap.org/node/5737771409";>Humanidades Edificio C</a>
+                    <br/>
+                    <ul>
+                        <li>Friday Core day, at Aula Magna</li>
+                    </ul>
+                </td>
+            </tr>            
+            <tr>
+                <td>
+                    <img src="/images/a-iv.jpg" alt="Aulario IV (A-IV) building" width="300px">
+                </td>
+                <td class="text-left">
+                    <a href="https://www.openstreetmap.org/way/37639116";>Aulario IV building</a>
+                    <br/>
+                    <ul>
+                        <li>Sat and Sun Core days, at Conference room</li>
+                        <li>Unconference, at 2nd floor</li>
+                    </ul>
+                </td>
+            </tr>
+        <tr>
+            <td>
+                <img src="/images/cafeteria.jpg" alt="UAL cafeteria" width="300px">
+            </td>
+            <td class="text-left">
+                <a href="https://www.openstreetmap.org/way/37639300";>University cafeteria</a>
+                <br/>
+                <ul>
+                    <li>Core days</li>
+                    <li>Unconference</li>
+                </ul>
+            </td>
+        </tr>
+        </tbody>
+    </table>
+</div>
+
+### ATM
+
+- There is an [ATM at campus](https://www.openstreetmap.org/node/999522025) just in front the main auditorum.
+- Near CIVITAS you'll find at least an ATM at [C/ Calzada de Castro, 
50](https://www.openstreetmap.org/node/4497678840).
+
+### Internet connectivity
+
+![UAL Campus](/images/CAMPUS_DESDE_EL_AULARIO_I_04.jpg){:width="200px" align="right"}
+
+There is a campus wide WiFi network. Network access is compatible with the  <a 
href="https://www.eduroam.org/"; >Eduroam network</a>
+accounts. GUADEquenses will have our own VLAN WiFi access activated in the places reserved for us.
+
+The campus has 3G/4G coverage from the main Spanish carriers.
+
+### On-site catering
+
+![UAL Cafeteria](/images/cafeteria-outside.jpg){:width="200px" align="right"}
+
+Meals will be held at the mentioned [campus cafeteria](https://www.openstreetmap.org/way/37639300).  It can 
host more
+than 300 persons at same time and is able to attend several hundreds in a normal day.  It offers healthy 
menus  following the Mediterranean
+diet includung salad, appetizer, main dish, dessert/fresh fruit, bread and drinks. 
[Gazpacho](https://commons.wikimedia.org/wiki/Category:Gazpacho) will be a GUADEC menu's special feature.
+
+In working days there are other smaller canteens but they all close at 14:00.
+
+
+### Maps
+
+Plus the [conference map](/pages/map.html) here it is a general map of the University of Almería campus:
+
+![UAL campus plan](/images/UAL-plan.png){:width="100%"}
diff --git a/content/pages/videos.md b/content/pages/videos.md
new file mode 100644
index 0000000..59d935d
--- /dev/null
+++ b/content/pages/videos.md
@@ -0,0 +1,13 @@
+Title: Videos
+Date: 20180912
+
+Finally GUADEC 2018 videos has been published thanks to the editing work of  Alexis Diavatis, Bin Li, 
Garrett LeSage, Alexandre Franke and Hubert Figuiere [leaded by Sam 
Thursfield](https://samthursfield.wordpress.com/2018/09/04/guadec-2018-videos-all-done/). Thank you all very 
much.
+
+All videos are being published at a [GUADEC 
2018](https://www.youtube.com/playlist?list=PLkmRdYgttscGT51fVXS1wR6ifOxc35W8e) playlist at Youtube:
+
+  <div style="margin-left:auto;margin-right:auto;margin-bottom:2em;width:560px;height:315px;">
+
+<iframe width="560px" height="315px" 
src="https://www.youtube.com/embed/videoseries?list=PLkmRdYgttscGT51fVXS1wR6ifOxc35W8e"; frameborder="0" 
allow="encrypted-media" allowfullscreen></iframe>
+</div>
+
+FYI: videos are archived too at <http://videos.guadec.org/2018>.
\ No newline at end of file
diff --git a/content/pages/visa.md b/content/pages/visa.md
new file mode 100644
index 0000000..bf2d830
--- /dev/null
+++ b/content/pages/visa.md
@@ -0,0 +1,120 @@
+Title: Getting an Spanish visa
+Date: 20180605
+Authors: ismael olea org
+
+
+## So you need a visa to get to GUADEC
+
+First all you should know you are travelling to the [Schengen 
Area](https://en.wikipedia.org/wiki/Schengen_Area)
+which Spain is part of. The reference information for traveling to Spain is on
+the [Ministry of Foreign Affairs website](http://www.exteriores.gob.es/Portal/en/Paginas/inicio.aspx),
+on the [information for 
foreighners](http://www.exteriores.gob.es/Portal/en/ServiciosAlCiudadano/InformacionParaExtranjeros/Paginas/RequisitosDeEntrada.aspx)
+page.
+
+You can check if you require a visa in
+[this list]( 
https://ec.europa.eu/home-affairs/sites/homeaffairs/files/what-we-do/policies/borders-and-visas/visa-policy/apply_for_a_visa/docs/visa_lists_en.pdf)
+(PDF).
+
+If you are required to have a visa, please read carefully the
+[entry requirements for 
foreighners](http://www.exteriores.gob.es/Portal/en/ServiciosAlCiudadano/InformacionParaExtranjeros/Paginas/RequisitosDeEntrada.aspx).
+
+Citing: 
+
+>##### At any event, entry may be refused (even with a valid passport and/or visa) at police checks in the 
following cases:
+>##### Journeys of a professional, political, scientific, sporting or religious nature or undertaken for 
other reasons
+>
+The presentation of any of the following documents may be required:
+>
+1.  Invitation from a company or an institution to take part in meetings, conferences, etc., of a 
commercial, industrial or similar nature.
+2. Document proving the existence of commercial, industrial relations, etc.
+3. Entry tickets to trade fairs, congresses, conventions, etc.
+4. Invitations, tickets, bookings or programmes indicating, as far as possible, the name of the host 
organisation and the duration of the stay, or any other document indicating the purpose of the visit.
+ 
+Consider too:
+>
+1.  A supporting document from the establishment providing accommodation <br/>
+IMPORTANT: Under no circumstances shall the letter of invitation replace the foreigner's accreditation of 
all other entry requirements.
+2.   A return or round-trip ticket.
+>
+In order to substantiate economic means, the provisions of Order PRE/1282/2007, of 10 May, on economic 
means, shall be taken into account, which provides that foreigners must demonstrate that they have sufficient 
means of support available in order to enter Spain. The minimum amount that must be substantiated is € 73.59 
per person per day, with a minimum of € 661.50 or its legal equivalent in foreign currency.
+
+The visa fee is usually 60.00 EUR.
+
+
+### How demostrate you have funds enough
+
+The way to do is showing their availability one way or other:
+
+- full cash
+- certified checks
+- travel checks
+- payment letters
+- credit cards, with a bank account statement up to date
+
+
+### Travel health insurance
+
+You need to contract an [Schengen Visa Travel 
Insurance](https://duckduckgo.com/?q=%22Schengen+Visa+Travel+Insurance%22&t=hf&ia=web) with 30,000€ minimum 
coverage. 
+
+[List of Schengen approved insurance companies 
2017](https://eeas.europa.eu/sites/eeas/files/schengen_approved_insurance_companies_2017_1.pdf).
+
+## Documentation for your travel
+
+Required documents:
+
+- approved visa document
+- valid passport
+- roudtrip flight tickets
+- two passport photos
+- Schengen travel insurance confirmation
+- invitation letter
+- conference ticket (if applicable)
+- proof of accommodation
+- proof of means to stay
+
+
+
+Extra documents could help at the Spanish border:
+
+- if employed: employment contract
+- if self-employed: copy of the business license
+- if student: proof of enrollment
+
+## Asking for an Spanish visa
+
+What you are going to ask for is a [Uniform Schengen 
Visa](http://www.exteriores.gob.es/Portal/en/ServiciosAlCiudadano/InformacionParaExtranjeros/Paginas/VisadosUniformeSchengen.aspx).
 Citing:
+
+>
+Short-stay visa requests should be made by submitting a printed copy of the correctly completed [official 
application](http://www.exteriores.gob.es/ContenidoReutilizable/InformacionParaExtranjeros/Documents/visadoSchengen_EN.pdf)
 (original and copy), which can be downloaded from this web page or obtained from the Diplomatic Missions or 
the Consular Offices of Spain abroad.
+>
+The visa should be requested in-person at the [Diplomatic Mission or Spanish Consular 
Office](http://www.exteriores.gob.es/Portal/es/ServiciosAlCiudadano/InformacionParaExtranjeros/Documents/Lista%20de%20Representaciones%20para%20la%20expedici%C3%B3n%20del%20visado%20uniforme.pdf)
 in the place where the applicant legally resides. If there is no Diplomatic Mission or Spanish Consular 
Office in a specific country, applications can be made at the Diplomatic Mission or Consular Office that 
represents Spain in said country.
+>
+The established fee must be paid when presenting the visa application. This will not be returned if the 
application is unsuccessful. The necessary requirements, as well as cases of reduction or waiver of the fee, 
should be checked at the Diplomatic Mission or Consular Office where the visa is requested, as these may vary 
depending on the applicant's reason for travel and country of origin.
+ >
+The maximum period to process a short-stay visa request is __15 calendar days__ from the date the 
application was made. This period may be extended to a maximum of 30 calendar days in certain circumstances. 
Exceptionally, in those specific cases where additional documentation is needed, this period can be extended 
to 60 calendar days. 
+ >
+The visa issued must be collected in-person from the corresponding Diplomatic Mission or Consular Office 
within a period of one month after the notification of its issuance. 
+ >
+If the visa is denied, the applicant will be notified by means of a standardised form which will state the 
reason for which the visa request was unsuccessful. In this situation, a Contentious-Administrative appeal 
can be lodged to the High Court of Justice (Tribunal Superior de Justicia) of Madrid within a term of two 
months from the date of notification. Appeals for reversal may be lodged with the Diplomatic Mission or 
Consular Office within a term of one month from the date of notification of the denial of visa. 
+
+Visa request form: [in 
English](http://www.exteriores.gob.es/ContenidoReutilizable/InformacionParaExtranjeros/Documents/visadoSchengen_EN.pdf)
 or [in 
Spanish](http://www.exteriores.gob.es/Portal/es/ServiciosAlCiudadano/InformacionParaExtranjeros/Documents/visadoSchengen_ES.pdf).
+
+[List of Spanish embassies and 
consulates](http://www.exteriores.gob.es/Portal/en/ServiciosAlCiudadano/Paginas/EmbajadasConsulados.aspx).
+
+In case you are interested (and could read Spanish) the procedure is regulated by the official [policy for 
foreigners in Spain](https://www.boe.es/buscar/act.php?id=BOE-A-2011-7703#).
+
+
+## Asking for a GUADEC invitation letter
+
+You should follow this process:
+[Instructions for Requesting an Invitation Letter](https://wiki.gnome.org/GUADEC/2018/Visa%20invitations)
+on the GNOME wiki.
+
+## Asking for the accommodation document
+
+You should ask your host/hotel/residence to send you a confirmation of your
+reservation.
+
+## More information
+
+You can find a lot of detailed information in websites like [Schengen Visa 
Information](https://www.schengenvisainfo.com/) (non-government affiliated).
\ No newline at end of file
diff --git a/devel.sh b/devel.sh
new file mode 100755
index 0000000..5cdb38d
--- /dev/null
+++ b/devel.sh
@@ -0,0 +1,49 @@
+#/bin/bash
+
+function quit {
+    #echo "Killing Grunt watcher"
+    #kill -9 $GRUNT_PID
+    echo "Killing HAMLPy watcher"
+    kill -9 $HAMLPY_PID
+    echo "Killing Pelican watcher"
+    kill -9 $PELICAN_PID
+    echo "Deactivating virtual environment"
+    deactivate
+}
+
+trap "quit" SIGINT
+
+if [ ! -d env ]; then
+    echo "Creating virtual environment"
+    virtualenv -p python3 env
+    echo "Activating virtual environment"
+    source ./env/bin/activate
+    echo "Installing python development dependencies"
+    pip install -r requirements.txt
+else
+    echo "Activating virtual environment"
+    source ./env/bin/activate
+fi
+
+if [ ! -d node_modules ]; then
+    echo "Installing node.js modules"
+    npm install
+fi
+
+echo "Executing grunt tasks and start watcher"
+grunt &
+grunt devel &
+GRUNT_PID=$!
+
+echo "Executing HAMLPy watcher"
+hamlpy-watcher ./src/haml/ ./themes/website/templates/ --attr-wrapper \" &
+HAMLPY_PID=$!
+
+echo "Executing pelican processor with autoreload"
+pelican -r &
+PELICAN_PID=$!
+
+echo "Executing pelican server"
+mkdir -p output
+cd output
+python -m pelican.server
diff --git a/guadec-web.doap b/guadec-web.doap
new file mode 100644
index 0000000..2cbe5d5
--- /dev/null
+++ b/guadec-web.doap
@@ -0,0 +1,36 @@
+<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#";
+         xmlns:foaf="http://xmlns.com/foaf/0.1/";
+         xmlns:gnome="http://api.gnome.org/doap-extensions#";
+         xmlns="http://usefulinc.com/ns/doap#";>
+
+  <name xml:lang="en">GUADEC Website</name>
+  <shortdesc xml:lang="en">GUADEC Website</shortdesc>
+  <description>
+       GUADEC is the annual GNOME Conference. This is the website for that.
+
+       Original theme design by Andreas Nilsson
+  </description>
+  <homepage rdf:resource="http://www.guadec.org"; />
+  <programming-language>Python</programming-language>
+  <mailing-list rdf:resource="http://mail.gnome.org/mailman/listinfo/guadec-list"; />
+  <bug-database rdf:resource="https://bugzilla.gnome.org/browse.cgi?product=website"; />
+
+  <category rdf:resource="http://api.gnome.org/doap-extensions#infrastructure"; />
+
+  <maintainer>
+    <foaf:Person>
+      <foaf:name>Oliver Gutierrez</foaf:name>
+      <foaf:mbox rdf:resource="mailto:ogutsua gmail com" />
+      <gnome:userid>ogutierrez</gnome:userid>
+    </foaf:Person>
+  </maintainer>
+
+  <maintainer>
+    <foaf:Person>
+      <foaf:name>Andreas Nilsson</foaf:name>
+      <foaf:mbox rdf:resource="mailto:andreas andreasn se" />
+      <gnome:userid>andreasn</gnome:userid>
+    </foaf:Person>
+  </maintainer>
+</Project>
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..4f4d492
--- /dev/null
+++ b/package.json
@@ -0,0 +1,15 @@
+{
+  "name": "website",
+  "version": "1.0.0",
+  "devDependencies": {
+    "grunt": "^0.4.5",
+    "grunt-contrib-compass": "^1.1.1",
+    "grunt-contrib-concat": "~0.5.1",
+    "grunt-contrib-copy": "^1.0.0",
+    "grunt-contrib-jshint": "~0.11.1",
+    "grunt-contrib-uglify": "~0.8.1",
+    "grunt-contrib-watch": "~1.0.0",
+    "grunt-jslint": "^1.1.15"
+  },
+  "dependencies": {}
+}
diff --git a/pelicanconf.py b/pelicanconf.py
new file mode 100644
index 0000000..97f91f5
--- /dev/null
+++ b/pelicanconf.py
@@ -0,0 +1,160 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*- #
+#
+# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+
+from __future__ import unicode_literals
+
+LANGUAGE_CODE = 'en'
+
+AUTHOR = 'GUADEC The GNOME Conference'
+SITENAME = 'GUADEC 2019'
+SITEYEAR = 2019
+SITEDOMAIN = 'localhost'
+SITEURL = 'http://%s:8000' % SITEDOMAIN
+
+GUADEC_LOCATION = "Thessaloniki, Greece"
+GUADEC_DATES = "August 23<sup>th</sup> - 28<sup>th</sup>"
+OPEN_REGISTRATION = False
+
+# Menu links
+MENU = {
+#    'Home': '/',
+#    'About the city': {
+#        'About the city of Almería': '/pages/about-almeria.html',
+#        'Tourism in Almería': '/pages/tourism-in-almeria.html',
+#    },
+#    'Map': '/pages/map.html',
+#    'Program': {
+#        'Proposals': '/pages/submit-a-proposal.html',
+#        'Schedule': '/pages/schedule.html',
+#        'Social events' : '/pages/social-events.html',
+#        'Venue': '/pages/venue.html',
+#        'Talks videos': '/pages/videos.html',
+
+#        '': None,
+#    },
+#    'Unconference': '/pages/unconference.html',
+#    'Travel': {
+#        'Getting there': '/pages/travel.html',
+#        'Main accommodation': '/pages/guadec-main-accommodation.html',
+#        'Other accommodation options': '/pages/other-accommodation-alternatives.html',
+#        'Visa': '/pages/getting-an-spanish-visa.html',
+#    },
+#    'Code of Conduct': {
+#        'Code of Conduct': '/pages/code-of-conduct.html',
+#        'Photo Policy': '/pages/photo-policy.html',
+#    },
+#    'Sponsors': '/pages/sponsors.html',
+#    'Media': {
+#        'Pictures gallery': 'https://www.flickr.com/groups/guadec2018/pool/',
+#        'Talks videos': '/pages/videos.html',
+#        'Materials': '/pages/materials.html',
+#        'Echo in press and  blogs': 'https://foro.hacklabalmeria.net/t/revista-de-prensa-guadec-2018/9093',
+#    },
+#    'Contact': '/pages/contact.html',
+}
+
+LINKS = (
+    ('The GNOME Project', 'https://www.gnome.org/'),
+    ('About Us', 'https://www.gnome.org/about/'),
+    ('Get Involved', 'https://www.gnome.org/get-involved/'),
+    ('Support GNOME', 'https://www.gnome.org/support-gnome/'),
+    ('Merchandise', 'https://www.gnome.org/merchandise/'),
+    ('Contact Us', 'https://www.gnome.org/contact/'),
+    ('Privacy', 'https://www.gnome.org/privacy/'),
+    ('The GNOME Foundation', 'https://www.gnome.org/foundation/'),
+)
+
+# GUADEC specific links
+GUADEC_LINKS = [
+    ('GUADEC: The GNOME conference', '/'),
+    #('News', '/category/news.html'),
+    #('Travel', '/pages/travel.html'),
+    #('Accommodation', '/pages/accommodation.html'),
+    #('Venue', '/pages/venue.html'),
+    # ('Location', '/pages/travel.html#location'),
+    #('Code of conduct', '/pages/code-of-conduct.html'),
+    #('Sponsors', '/pages/sponsors.html'),
+]
+
+# Add registration link only if registration is open
+if OPEN_REGISTRATION:
+    GUADEC_LINKS.append(
+        ('Register', 'https://registration.guadec.org/'))
+
+# Social networks
+SOCIAL = (
+    ('Twitter', 'https://twitter.com/GUADEC'),
+    # ('Telegram', 'https://t.me/GUADEC'),
+    ('Mail', 'https://mail.gnome.org/mailman/listinfo/guadec-list'),
+    # ('Matrix', '#_gimpnet_#guadec:matrix.org'), or whatever works!
+    # ('Facebook', 'https://www.facebook.com/GNOMEDesktop'),
+    # ('Twitter', 'https://twitter.com/gnome'),
+    # ('Google Plus', 'https://plus.google.com/+gnome'),
+    # ('Youtube', 'https://www.youtube.com/user/GNOMEDesktop'),
+    # ('Instagram', 'https://instagram.com/'),
+    # ('Pinterest', 'https://pinterest.com/'),
+)
+
+SPONSORS = (
+    #('Private Internet Access', 'https://www.privateinternetaccess.com/', 'pia.png'),
+    #('Red Hat', 'https://www.redhat.com/', 'redhat.png'),
+    #('Endless', 'https://endlessos.com/', 'endless.png'),
+    #('Canonical', 'https://www.ubuntu.com', 'canonical.png'),
+    #('OpenSUSE', 'http://www.opensuse.org/', 'opensuse.png'),
+    #('Codethink', 'https://www.codethink.co.uk/', 'codethink.png'),
+    #('GitLab', 'https://gitlab.com', 'gitlab.png'),
+    #('Igalia', 'https://www.igalia.com/', 'igalia.png'),
+    #('Arm', 'https://www.arm.com/', 'arm.png'),
+    # ('Google', 'https://opensource.google.com/', 'google.png'),
+    # ('Mozilla Foundation', 'http://www.mozilla.org/', 'mozilla.png'),
+    # ('Collabora', 'https://www.collabora.com/', 'collabora.png'),
+)
+
+#------------------------------------------------------------------------------
+# Pelican settings
+#------------------------------------------------------------------------------
+PATH = 'content'
+TIMEZONE = 'GMT'
+DEFAULT_LANG = u'en'
+THEME = 'themes/website'
+DEFAULT_PAGINATION = False
+DISPLAY_PAGES_ON_MENU = False
+STATIC_PATHS = ['images', 'documents']
+ARTICLE_EXCLUDES = ['images', 'documents']
+# Uncomment following line if you want document-relative URLs when developing
+# RELATIVE_URLS = True
+
+# Feed generation is usually not desired when developing
+FEED_ALL_ATOM = None
+CATEGORY_FEED_ATOM = None
+TRANSLATION_FEED_ATOM = None
+AUTHOR_FEED_ATOM = None
+AUTHOR_FEED_RSS = None
+
+MARKDOWN = {
+    'extension_configs': {
+        'markdown.extensions.extra': {},
+    },
+    'output_format': 'html5',
+}
diff --git a/publishconf.py b/publishconf.py
new file mode 100644
index 0000000..c15137c
--- /dev/null
+++ b/publishconf.py
@@ -0,0 +1,46 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*- #
+#
+# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+#
+# Permission is hereby granted, free of charge, to any person obtaining a copy of
+# this software and associated documentation files (the "Software"), to deal in
+# the Software without restriction, including without limitation the rights to
+# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+# of the Software, and to permit persons to whom the Software is furnished to do
+# so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included in all
+# copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+# SOFTWARE.
+
+from __future__ import unicode_literals
+
+import os
+import sys
+sys.path.append(os.curdir)
+from pelicanconf import *
+
+LANGUAGE_CODE = 'en'
+
+SITEDOMAIN = '2019.guadec.org'
+SITEURL = 'https://%s' % SITEDOMAIN
+
+RELATIVE_URLS = False
+
+FEED_ALL_ATOM = 'feeds/all.atom.xml'
+CATEGORY_FEED_ATOM = 'feeds/%s.atom.xml'
+
+DELETE_OUTPUT_DIRECTORY = True
+
+# Following items are often useful when publishing
+
+#DISQUS_SITENAME = ""
+#GOOGLE_ANALYTICS = ""
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..e6b1983
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,13 @@
+blinker==1.4
+docutils==0.14
+feedgenerator==1.9
+Jinja2==2.9.6
+Markdown==2.6.9
+MarkupSafe==1.0
+pelican==3.7.1
+Pygments==2.2.0
+python-dateutil==2.6.1
+pytz==2017.2
+six==1.11.0
+Unidecode==0.4.21
+django-hamlpy
diff --git a/src/fonts/SourceSansPro-Regular.otf b/src/fonts/SourceSansPro-Regular.otf
new file mode 100644
index 0000000..bdcfb27
Binary files /dev/null and b/src/fonts/SourceSansPro-Regular.otf differ
diff --git a/src/fonts/cantarell-bold.woff b/src/fonts/cantarell-bold.woff
new file mode 100755
index 0000000..7eada1e
Binary files /dev/null and b/src/fonts/cantarell-bold.woff differ
diff --git a/src/fonts/cantarell-bold.woff2 b/src/fonts/cantarell-bold.woff2
new file mode 100755
index 0000000..80699a7
Binary files /dev/null and b/src/fonts/cantarell-bold.woff2 differ
diff --git a/src/fonts/open-iconic.eot b/src/fonts/open-iconic.eot
new file mode 100644
index 0000000..f98177d
Binary files /dev/null and b/src/fonts/open-iconic.eot differ
diff --git a/src/fonts/open-iconic.otf b/src/fonts/open-iconic.otf
new file mode 100644
index 0000000..f6bd684
Binary files /dev/null and b/src/fonts/open-iconic.otf differ
diff --git a/src/fonts/open-iconic.svg b/src/fonts/open-iconic.svg
new file mode 100644
index 0000000..32b2c4e
--- /dev/null
+++ b/src/fonts/open-iconic.svg
@@ -0,0 +1,543 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"; >
+<!--
+2014-7-1: Created.
+-->
+<svg xmlns="http://www.w3.org/2000/svg";>
+<metadata>
+Created by FontForge 20120731 at Tue Jul  1 20:39:22 2014
+ By P.J. Onori
+Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net)
+</metadata>
+<defs>
+<font id="open-iconic" horiz-adv-x="800" >
+  <font-face 
+    font-family="Icons"
+    font-weight="400"
+    font-stretch="normal"
+    units-per-em="800"
+    panose-1="2 0 5 3 0 0 0 0 0 0"
+    ascent="800"
+    descent="0"
+    bbox="-0.5 -101 802 800.126"
+    underline-thickness="50"
+    underline-position="-100"
+    unicode-range="U+E000-E0DE"
+  />
+    <missing-glyph />
+    <glyph glyph-name="" unicode="&#xe000;" 
+d="M300 700h500v-700h-500v100h400v500h-400v100zM400 500l200 -150l-200 -150v100h-400v100h400v100z" />
+    <glyph glyph-name="1" unicode="&#xe001;" 
+d="M300 700h500v-700h-500v100h400v500h-400v100zM200 500v-100h400v-100h-400v-100l-200 150z" />
+    <glyph glyph-name="2" unicode="&#xe002;" 
+d="M350 700c193 0 350 -157 350 -350v-50h100l-200 -200l-200 200h100v50c0 138 -112 250 -250 250s-250 -112 -250 
-250c0 193 157 350 350 350z" />
+    <glyph glyph-name="3" unicode="&#xe003;" 
+d="M450 700c193 0 350 -157 350 -350c0 138 -112 250 -250 250s-250 -112 -250 -250v-50h100l-200 -200l-200 
200h100v50c0 193 157 350 350 350z" />
+    <glyph glyph-name="4" unicode="&#xe004;" 
+d="M0 700h800v-100h-800v100zM100 500h600v-100h-600v100zM0 300h800v-100h-800v100zM100 100h600v-100h-600v100z" 
/>
+    <glyph glyph-name="5" unicode="&#xe005;" 
+d="M0 700h800v-100h-800v100zM0 500h600v-100h-600v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100z" />
+    <glyph glyph-name="6" unicode="&#xe006;" 
+d="M0 700h800v-100h-800v100zM200 500h600v-100h-600v100zM0 300h800v-100h-800v100zM200 100h600v-100h-600v100z" 
/>
+    <glyph glyph-name="7" unicode="&#xe007;" 
+d="M400 700c75 0 146 -23 206 -59l-75 -225l-322 234c57 31 122 50 191 50zM125 588l191 -138l-310 -222c-4 24 -6 
47 -6 72c0 114 49 215 125 288zM688 575c69 -72 112 -168 112 -275c0 -35 -8 -68 -16 -100h-218zM216 253l112 
-347c-128 23 -232 109 -287 222zM372 100
+h372c-64 -109 -177 -185 -310 -197z" />
+    <glyph glyph-name="8" unicode="&#xe008;" horiz-adv-x="600" 
+d="M200 800h100v-500h200l-247 -300l-253 300h200v500z" />
+    <glyph glyph-name="9" unicode="&#xe009;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM300 
700v-300h-200l300 -300l300 300h-200v300h-200z" />
+    <glyph glyph-name="a" unicode="&#xe00a;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700l-300 
-300l300 -300v200h300v200h-300v200z" />
+    <glyph glyph-name="b" unicode="&#xe00b;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 
700v-200h-300v-200h300v-200l300 300z" />
+    <glyph glyph-name="c" unicode="&#xe00c;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700l-300 
-300h200v-300h200v300h200z" />
+    <glyph glyph-name="d" unicode="&#xe00d;" 
+d="M300 600v-200h500v-100h-500v-200l-300 247z" />
+    <glyph glyph-name="e" unicode="&#xe00e;" 
+d="M500 600l300 -247l-300 -253v200h-500v100h500v200z" />
+    <glyph glyph-name="f" unicode="&#xe00f;" horiz-adv-x="600" 
+d="M200 800h200v-500h200l-297 -300l-303 300h200v500z" />
+    <glyph glyph-name="10" unicode="&#xe010;" 
+d="M300 700v-200h500v-200h-500v-200l-300 297z" />
+    <glyph glyph-name="11" unicode="&#xe011;" 
+d="M500 700l300 -297l-300 -303v200h-500v200h500v200z" />
+    <glyph glyph-name="12" unicode="&#xe012;" horiz-adv-x="600" 
+d="M297 800l303 -300h-200v-500h-200v500h-200z" />
+    <glyph glyph-name="13" unicode="&#xe013;" horiz-adv-x="600" 
+d="M247 800l253 -300h-200v-500h-100v500h-200z" />
+    <glyph glyph-name="14" unicode="&#xe014;" 
+d="M400 800h100v-800h-100v800zM200 700h100v-600h-100v600zM600 600h100v-400h-100v400zM0 
500h100v-200h-100v200z" />
+    <glyph glyph-name="15" unicode="&#xe015;" 
+d="M116 600l72 -72c-54 -54 -88 -126 -88 -209s34 -159 88 -213l-72 -72c-72 72 -116 175 -116 285s44 209 116 
281zM684 600c72 -72 116 -171 116 -281s-44 -213 -116 -285l-72 72c54 54 88 130 88 213s-34 155 -88 209zM259 
460l69 -72c-18 -18 -28 -41 -28 -69
+s10 -54 28 -72l-69 -72c-36 36 -59 89 -59 144s23 105 59 141zM541 459c36 -36 59 -85 59 -140s-23 -108 -59 
-144l-69 72c18 18 28 44 28 72s-10 51 -28 69z" />
+    <glyph glyph-name="16" unicode="&#xe016;" horiz-adv-x="400" 
+d="M200 800c110 0 200 -90 200 -200s-90 -200 -200 -200s-200 90 -200 200s90 200 200 200zM100 319c31 -11 65 -19 
100 -19s68 8 100 19v-319l-100 100l-100 -100v319z" />
+    <glyph glyph-name="17" unicode="&#xe017;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 
-300 -134 -300 -300c0 -66 21 -126 56 -175l419 419c-49 35 -109 56 -175 56zM644 575l-419 -419c49 -35 109 -56 
175 -56c166 0 300 134 300 300
+c0 66 -21 126 -56 175z" />
+    <glyph glyph-name="18" unicode="&#xe018;" 
+d="M0 700h100v-600h700v-100h-800v700zM500 700h200v-500h-200v500zM200 500h200v-300h-200v300z" />
+    <glyph glyph-name="19" unicode="&#xe019;" 
+d="M397 800c13 1 23 -4 34 -13c2 -2 214 -254 241 -287h128v-100h-100v-366c0 -18 -16 -34 -34 -34h-532c-18 0 -34 
16 -34 34v366h-100v100h128l234 281c9 11 22 18 35 19zM400 672l-144 -172h288zM250 300c-28 0 -50 -22 -50 
-50v-100c0 -28 22 -50 50 -50s50 22 50 50
+v100c0 28 -22 50 -50 50zM550 300c-28 0 -50 -22 -50 -50v-100c0 -28 22 -50 50 -50s50 22 50 50v100c0 28 -22 50 
-50 50z" />
+    <glyph glyph-name="1a" unicode="&#xe01a;" 
+d="M9 700h682c6 0 9 -4 9 -10v-190h100v-200h-100v-191c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v582c0 6 3 9 9 
9zM100 600v-400h500v400h-500z" />
+    <glyph glyph-name="1b" unicode="&#xe01b;" 
+d="M9 700h682c6 0 9 -4 9 -10v-190h100v-200h-100v-191c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v582c0 6 3 9 9 9z" 
/>
+    <glyph glyph-name="1c" unicode="&#xe01c;" 
+d="M92 650c0 23 19 50 45 50h3h5h5h500c28 0 50 -22 50 -50s-22 -50 -50 -50h-50v-141c9 -17 120 -231 166 -309c16 
-26 34 -61 34 -106c0 -39 -15 -77 -41 -103h-3c-26 -25 -62 -41 -100 -41h-512c-39 0 -77 15 -103 41s-41 64 -41 
103c0 46 18 80 34 106
+c46 78 157 292 166 309v141h-50c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 51zM500 600h-200v-162l-6 -10s-63 -123 -119 
-228h450c-56 105 -119 228 -119 228l-6 10v162z" />
+    <glyph glyph-name="1d" unicode="&#xe01d;" 
+d="M400 800c110 0 200 -90 200 -200c0 -104 52 -198 134 -266c41 -34 66 -82 66 -134h-800c0 52 25 100 66 134c82 
68 134 162 134 266c0 110 90 200 200 200zM300 100h200c0 -55 -45 -100 -100 -100s-100 45 -100 100z" />
+    <glyph glyph-name="1e" unicode="&#xe01e;" horiz-adv-x="600" 
+d="M150 800h50l350 -250l-225 -147l225 -153l-350 -250h-50v250l-75 -75l-75 75l150 150l-150 150l75 75l75 
-75v250zM250 650v-200l150 100zM250 350v-200l150 100z" />
+    <glyph glyph-name="1f" unicode="&#xe01f;" 
+d="M0 800h500c110 0 200 -90 200 -200c0 -47 -17 -91 -44 -125c85 -40 144 -125 144 -225c0 -138 -112 -250 -250 
-250h-550v100c55 0 100 45 100 100v400c0 55 -45 100 -100 100v100zM300 700v-200h100c55 0 100 45 100 100s-45 100 
-100 100h-100zM300 400v-300h150
+c83 0 150 67 150 150s-67 150 -150 150h-150z" />
+    <glyph glyph-name="20" unicode="&#xe020;" horiz-adv-x="600" 
+d="M300 800v-300h200l-300 -500v300h-200z" />
+    <glyph glyph-name="21" unicode="&#xe021;" 
+d="M100 800h300v-300l100 100l100 -100v300h50c28 0 50 -22 50 -50v-550h-550c-28 0 -50 -22 -50 -50s22 -50 50 
-50h550v-100h-550c-83 0 -150 67 -150 150v550l3 19c8 39 39 70 78 78z" />
+    <glyph glyph-name="22" unicode="&#xe022;" horiz-adv-x="400" 
+d="M0 800h400v-800l-200 200l-200 -200v800z" />
+    <glyph glyph-name="23" unicode="&#xe023;" 
+d="M0 800h800v-100h-800v100zM0 600h300v-103h203v103h297v-591c0 -6 -3 -9 -9 -9h-782c-6 0 -9 3 -9 9v591z" />
+    <glyph glyph-name="24" unicode="&#xe024;" 
+d="M300 800h200c55 0 100 -45 100 -100v-100h191c6 0 9 -3 9 -9v-241c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 
-50 50v241c0 6 3 9 9 9h191v100c0 55 45 100 100 100zM300 700v-100h200v100h-200zM0 209c16 -6 32 -9 50 -9h700c18 
0 34 3 50 9v-200c0 -6 -3 -9 -9 -9h-782
+c-6 0 -9 3 -9 9v200z" />
+    <glyph glyph-name="25" unicode="&#xe025;" horiz-adv-x="600" 
+d="M300 800c58 0 110 -16 147 -53s53 -89 53 -147h-100c0 39 -11 61 -25 75s-36 25 -75 25c-35 0 -55 -10 -72 
-31s-28 -55 -28 -94c0 -51 20 -107 28 -175h172v-100h-178c-14 -60 -49 -127 -113 -200h491v-100h-600v122l16 12c69 
69 95 121 106 166h-122v100h125
+c-8 50 -25 106 -25 175c0 58 16 114 50 156c34 43 88 69 150 69z" />
+    <glyph glyph-name="26" unicode="&#xe026;" 
+d="M34 700h4h3h4h5h700c28 0 50 -22 50 -50v-700c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v700v2c0 20 15 
42 34 48zM150 600c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50zM350 600c-28 0 -50 -22 -50 
-50s22 -50 50 -50h300c28 0 50 22 50 50
+s-22 50 -50 50h-300zM100 400v-400h600v400h-600z" />
+    <glyph glyph-name="27" unicode="&#xe027;" 
+d="M744 797l6 -3l44 -44c4 -4 3 -8 0 -12l-266 -375l-15 -13l-25 -12c-23 72 -78 127 -150 150l12 25l13 15l375 
266zM266 400c74 0 134 -60 134 -134c0 -147 -119 -266 -266 -266c-48 0 -95 12 -134 34c80 46 134 133 134 232c0 74 
58 134 132 134z" />
+    <glyph glyph-name="28" unicode="&#xe028;" 
+d="M9 451c0 23 19 50 46 50c8 0 19 -3 26 -7l131 -66l29 22c-79 81 -1 250 118 250s197 -167 119 -250l28 -22l131 
66c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-115 -56c9 -16 19 -33 25 -50h68c28 0 50 -22 50 
-50s-22 -50 -50 -50h-50
+c0 -23 -2 -45 -6 -66l78 -40c21 -5 37 -28 37 -49c0 -28 -22 -50 -50 -50c-10 0 -23 5 -31 11l-65 35c-24 -46 -62 
-86 -103 -110c-35 19 -60 45 -60 72v135v4v5v6v5v5v87c0 28 -22 50 -50 50c-24 0 -45 -17 -50 -40c1 -3 1 -8 1 
-11s0 -8 -1 -11v-82v-4v-5v-144
+c0 -28 -24 -53 -59 -72c-41 25 -79 64 -103 110l-66 -35c-8 -6 -21 -11 -31 -11c-28 0 -50 22 -50 50c0 21 16 44 
37 49l78 40c-4 21 -6 43 -6 66h-50h-5c-28 0 -50 22 -50 50c0 26 22 50 50 50h5h69c6 17 16 34 25 50l-116 56c-16 7 
-28 27 -28 45z" />
+    <glyph glyph-name="29" unicode="&#xe029;" 
+d="M600 700h91c6 0 9 -3 9 -9v-582c0 -6 -3 -9 -9 -9h-91v600zM210 503l290 147v-500l-250 125v-3c-15 0 -25 -8 
-28 -22l75 -178c11 -25 0 -58 -25 -69s-58 0 -69 25l-103 272h-91c-6 0 -9 3 -9 9v182c0 6 3 9 9 9h182z" />
+    <glyph glyph-name="2a" unicode="&#xe02a;" 
+d="M9 800h682c6 0 9 -3 9 -9v-782c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v782c0 6 3 9 9 9zM100 
700v-200h500v200h-500zM100 400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400v-300h100v300h-100zM100 
200v-100h100v100h-100zM300 200v-100h100v100h-100z" />
+    <glyph glyph-name="2b" unicode="&#xe02b;" 
+d="M0 800h700v-200h-700v200zM0 500h700v-491c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v491zM100 
400v-100h100v100h-100zM300 400v-100h100v100h-100zM500 400v-100h100v100h-100zM100 200v-100h100v100h-100zM300 
200v-100h100v100h-100z" />
+    <glyph glyph-name="2c" unicode="&#xe02c;" 
+d="M409 800h182c6 0 10 -4 12 -9l94 -182c2 -5 6 -9 12 -9h82c6 0 9 -3 9 -9v-582c0 -6 -3 -9 -9 -9h-782c-6 0 -9 
3 -9 9v441c0 83 67 150 150 150h141c6 0 10 4 12 9l94 182c2 5 6 9 12 9zM150 500c-28 0 -50 -22 -50 -50s22 -50 50 
-50s50 22 50 50s-22 50 -50 50z
+M500 500c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200zM500 400c55 0 100 -45 
100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
+    <glyph glyph-name="2d" unicode="&#xe02d;" 
+d="M0 600h800l-400 -400z" />
+    <glyph glyph-name="2e" unicode="&#xe02e;" horiz-adv-x="400" 
+d="M400 800v-800l-400 400z" />
+    <glyph glyph-name="2f" unicode="&#xe02f;" horiz-adv-x="400" 
+d="M0 800l400 -400l-400 -400v800z" />
+    <glyph glyph-name="30" unicode="&#xe030;" 
+d="M400 600l400 -400h-800z" />
+    <glyph glyph-name="31" unicode="&#xe031;" 
+d="M0 550c0 23 20 50 46 50h3h5h4h200c17 0 37 -13 44 -28l38 -72h444c14 0 19 -12 15 -25l-81 -250c-4 -13 -21 
-25 -35 -25h-350c-14 0 -30 12 -34 25c-27 83 -54 167 -81 250l-10 25h-150c-2 0 -5 -1 -7 -1c-28 0 -51 23 -51 
51zM358 100c28 0 50 -22 50 -50
+s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM658 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 
50 50z" />
+    <glyph glyph-name="32" unicode="&#xe032;" 
+d="M0 700h500v-100h-300v-300h-100l-100 -100v500zM300 500h500v-500l-100 100h-400v400z" />
+    <glyph glyph-name="33" unicode="&#xe033;" 
+d="M641 700l143 -141l-493 -493c-71 76 -146 148 -219 222l-72 71l141 141c50 -51 101 -101 153 -150c116 117 234 
231 347 350z" />
+    <glyph glyph-name="34" unicode="&#xe034;" 
+d="M150 600l250 -250l250 250l150 -150l-400 -400l-400 400z" />
+    <glyph glyph-name="35" unicode="&#xe035;" horiz-adv-x="600" 
+d="M400 800l150 -150l-250 -250l250 -250l-150 -150l-400 400z" />
+    <glyph glyph-name="36" unicode="&#xe036;" horiz-adv-x="600" 
+d="M150 800l400 -400l-400 -400l-150 150l250 250l-250 250z" />
+    <glyph glyph-name="37" unicode="&#xe037;" 
+d="M400 600l400 -400l-150 -150l-250 250l-250 -250l-150 150z" />
+    <glyph glyph-name="38" unicode="&#xe038;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM600 622l-250 
-250l-100 100l-72 -72l172 -172l322 322z" />
+    <glyph glyph-name="39" unicode="&#xe039;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM250 622l-72 
-72l150 -150l-150 -150l72 -72l150 150l150 -150l72 72l-150 150l150 150l-72 72l-150 -150z" />
+    <glyph glyph-name="3a" unicode="&#xe03a;" 
+d="M350 800c28 0 50 -22 50 -50v-50h75c14 0 25 -11 25 -25v-75h-300v75c0 14 11 25 25 25h75v50c0 28 22 50 50 
50zM25 700h75v-200h500v200h75c14 0 25 -11 25 -25v-650c0 -14 -11 -25 -25 -25h-650c-14 0 -25 11 -25 25v650c0 14 
11 25 25 25z" />
+    <glyph glyph-name="3b" unicode="&#xe03b;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 
-300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM350 600h100v-181c23 -24 47 -47 72 
-69l-72 -72c-27 30 -55 59 -84 88l-16 12
+v222z" />
+    <glyph glyph-name="3c" unicode="&#xe03c;" 
+d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -18 -3 -34 -9 -50h-191v50c0 83 -67 150 
-150 150s-150 -67 -150 -150v-50h-272c-17 30 -28 63 -28 100c0 110 90 200 200 200c23 114 129 200 250 200zM434 
400h3h4c3 0 6 1 9 1c28 0 50 -22 50 -50v-1
+v-150h150l-200 -200l-200 200h150v150v2c0 20 15 42 34 48z" />
+    <glyph glyph-name="3d" unicode="&#xe03d;" 
+d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -18 -3 -34 -9 -50h-141l-200 200l-200 
-200h-222c-17 30 -28 63 -28 100c0 110 90 200 200 200c23 114 129 200 250 200zM450 350l250 -250h-200v-50c0 -28 
-22 -50 -50 -50s-50 22 -50 50v50h-200z" />
+    <glyph glyph-name="3e" unicode="&#xe03e;" 
+d="M450 700c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -83 -67 -150 -150 -150h-450c-110 0 -200 90 
-200 200s90 200 200 200c23 114 129 200 250 200z" />
+    <glyph glyph-name="3f" unicode="&#xe03f;" 
+d="M250 800c82 0 154 -40 200 -100c-143 0 -270 -85 -325 -209c-36 -10 -70 -25 -100 -47c-16 33 -25 67 -25 106c0 
138 112 250 250 250zM450 600c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -83 -67 -150 -150 
-150h-450c-110 0 -200 90 -200 200
+s90 200 200 200c23 114 129 200 250 200z" />
+    <glyph glyph-name="40" unicode="&#xe040;" 
+d="M500 700h100l-300 -600h-100zM100 600h100l-100 -200l100 -200h-100l-100 200zM600 600h100l100 -200l-100 
-200h-100l100 200z" />
+    <glyph glyph-name="41" unicode="&#xe041;" 
+d="M350 800h100l50 -119l28 -12l119 50l72 -72l-50 -119l12 -28l119 -50v-100l-119 -50l-12 -28l50 -119l-72 
-72l-119 50l-28 -12l-50 -119h-100l-50 119l-28 12l-119 -50l-72 72l50 119l-12 28l-119 50v100l119 50l12 28l-50 
119l72 72l119 -50l28 12zM400 550
+c-83 0 -150 -67 -150 -150s67 -150 150 -150s150 67 150 150s-67 150 -150 150z" />
+    <glyph glyph-name="42" unicode="&#xe042;" 
+d="M0 800h800v-200h-800v200zM200 500h400l-200 -200zM0 100h800v-100h-800v100z" />
+    <glyph glyph-name="43" unicode="&#xe043;" 
+d="M0 800h100v-800h-100v800zM600 800h200v-800h-200v800zM500 600v-400l-200 200z" />
+    <glyph glyph-name="44" unicode="&#xe044;" 
+d="M0 800h200v-800h-200v800zM700 800h100v-800h-100v800zM300 600l200 -200l-200 -200v400z" />
+    <glyph glyph-name="45" unicode="&#xe045;" 
+d="M0 800h800v-100h-800v100zM400 500l200 -200h-400zM0 200h800v-200h-800v200z" />
+    <glyph glyph-name="46" unicode="&#xe046;" 
+d="M150 700c83 0 150 -67 150 -150v-50h100v50c0 83 67 150 150 150s150 -67 150 -150s-67 -150 -150 
-150h-50v-100h50c83 0 150 -67 150 -150s-67 -150 -150 -150s-150 67 -150 150v50h-100v-50c0 -83 -67 -150 -150 
-150s-150 67 -150 150s67 150 150 150h50v100h-50
+c-83 0 -150 67 -150 150s67 150 150 150zM150 600c-28 0 -50 -22 -50 -50s22 -50 50 -50h50v50c0 28 -22 50 -50 
50zM550 600c-28 0 -50 -22 -50 -50v-50h50c28 0 50 22 50 50s-22 50 -50 50zM300 400v-100h100v100h-100zM150 
200c-28 0 -50 -22 -50 -50s22 -50 50 -50
+s50 22 50 50v50h-50zM500 200v-50c0 -28 22 -50 50 -50s50 22 50 50s-22 50 -50 50h-50z" />
+    <glyph glyph-name="47" unicode="&#xe047;" 
+d="M0 791c0 5 4 9 9 9h782c6 0 9 -4 9 -10v-790l-200 200h-591c-6 0 -9 3 -9 9v582z" />
+    <glyph glyph-name="48" unicode="&#xe048;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 
-300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM600 600l-100 -300l-300 -100l100 
300zM400 450c-28 0 -50 -22 -50 -50
+s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="49" unicode="&#xe049;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700v-600c166 
0 300 134 300 300s-134 300 -300 300z" />
+    <glyph glyph-name="4a" unicode="&#xe04a;" 
+d="M0 800h800v-100h-800v100zM0 600h500v-100h-500v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100zM750 
100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
+    <glyph glyph-name="4b" unicode="&#xe04b;" 
+d="M25 700h750c14 0 25 -11 25 -25v-75h-800v75c0 14 11 25 25 25zM0 500h800v-375c0 -14 -11 -25 -25 
-25h-750c-14 0 -25 11 -25 25v375zM100 300v-100h100v100h-100zM300 300v-100h100v100h-100z" />
+    <glyph glyph-name="4c" unicode="&#xe04c;" 
+d="M100 800h100v-100h450l100 100l50 -50l-100 
-100v-450h100v-100h-100v-100h-100v100h-500v500h-100v100h100v100zM200 600v-350l350 350h-350zM600 550l-350 
-350h350v350z" />
+    <glyph glyph-name="4d" unicode="&#xe04d;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 
-300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM400 600c28 0 50 -22 50 -50s-22 -50 
-50 -50s-50 22 -50 50s22 50 50 50z
+M200 452c0 20 15 42 34 48h3h3h8c12 0 28 -7 36 -16l91 -90l25 6c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 
45 -100 100l6 25l-90 91c-9 8 -16 24 -16 36zM550 500c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 
50z" />
+    <glyph glyph-name="4e" unicode="&#xe04e;" 
+d="M300 800h200v-300h200l-300 -300l-300 300h200v300zM0 100h800v-100h-800v100z" />
+    <glyph glyph-name="4f" unicode="&#xe04f;" 
+d="M0 800h800v-100h-800v100zM400 600l300 -300h-200v-300h-200v300h-200z" />
+    <glyph glyph-name="50" unicode="&#xe050;" 
+d="M200 700h600v-600h-600l-200 300zM350 622l-72 -72l150 -150l-150 -150l72 -72l150 150l150 -150l72 72l-150 
150l150 150l-72 72l-150 -150z" />
+    <glyph glyph-name="51" unicode="&#xe051;" 
+d="M400 700c220 0 400 -180 400 -400h-100c0 166 -134 300 -300 300s-300 -134 -300 -300h-100c0 220 180 400 400 
400zM341 491l59 -88l59 88c81 -25 141 -101 141 -191c0 -110 -90 -200 -200 -200s-200 90 -200 200c0 90 60 166 141 
191z" />
+    <glyph glyph-name="52" unicode="&#xe052;" 
+d="M0 800h300v-400h400v-400h-700v800zM400 800l300 -300h-300v300zM100 600v-100h100v100h-100zM100 
400v-100h100v100h-100zM100 200v-100h400v100h-400z" />
+    <glyph glyph-name="53" unicode="&#xe053;" horiz-adv-x="600" 
+d="M200 700h100v-100h75c30 0 58 -6 81 -22s44 -44 44 -78v-100h-100v94c-4 3 -13 6 -25 6h-250c-14 0 -25 -11 -25 
-25v-50c0 -15 20 -40 34 -44l257 -65c66 -16 109 -73 109 -141v-50c0 -68 -57 -125 -125 
-125h-75v-100h-100v100h-75c-30 0 -58 6 -81 22s-44 44 -44 78
+v100h100v-94c4 -3 13 -6 25 -6h250c14 0 25 11 25 25v50c0 15 -20 40 -34 44l-257 65c-66 16 -109 73 -109 
141v50c0 68 57 125 125 125h75v100z" />
+    <glyph glyph-name="54" unicode="&#xe054;" 
+d="M0 700h300v-300l-300 -300v600zM500 700h300v-300l-300 -300v600z" />
+    <glyph glyph-name="55" unicode="&#xe055;" 
+d="M300 700v-600h-300v300zM800 700v-600h-300v300z" />
+    <glyph glyph-name="56" unicode="&#xe056;" 
+d="M300 700v-100c-111 0 -200 -89 -200 -200h200v-300h-300v300c0 165 135 300 300 300zM800 700v-100c-111 0 -200 
-89 -200 -200h200v-300h-300v300c0 165 135 300 300 300z" />
+    <glyph glyph-name="57" unicode="&#xe057;" 
+d="M0 700h300v-300c0 -165 -135 -300 -300 -300v100c111 0 200 89 200 200h-200v300zM500 700h300v-300c0 -165 
-135 -300 -300 -300v100c111 0 200 89 200 200h-200v300z" />
+    <glyph glyph-name="58" unicode="&#xe058;" horiz-adv-x="600" 
+d="M300 800l34 -34c11 -11 266 -270 266 -488c0 -165 -135 -300 -300 -300s-300 135 -300 300c0 218 255 477 266 
488zM150 328c-28 0 -50 -22 -50 -50c0 -110 90 -200 200 -200c28 0 50 22 50 50s-22 50 -50 50c-55 0 -100 45 -100 
100c0 28 -22 50 -50 50z" />
+    <glyph glyph-name="59" unicode="&#xe059;" 
+d="M400 800l400 -500h-800zM0 200h800v-200h-800v200z" />
+    <glyph glyph-name="5a" unicode="&#xe05a;" horiz-adv-x="600" 
+d="M300 800l300 -300h-600zM0 300h600l-300 -300z" />
+    <glyph glyph-name="5b" unicode="&#xe05b;" 
+d="M0 500h200v-200h-200v200zM300 500h200v-200h-200v200zM600 500h200v-200h-200v200z" />
+    <glyph glyph-name="5c" unicode="&#xe05c;" 
+d="M0 700h800v-100l-400 -200l-400 200v100zM0 500l400 -200l400 200v-400h-800v400z" />
+    <glyph glyph-name="5d" unicode="&#xe05d;" 
+d="M400 800l400 -200v-600h-800v600zM400 688l-300 -150v-188l300 -150l300 150v188zM200 500h400v-100l-200 
-100l-200 100v100z" />
+    <glyph glyph-name="5e" unicode="&#xe05e;" 
+d="M600 700c69 0 134 -19 191 -50l-16 -106c-49 35 -109 56 -175 56c-131 0 -240 -84 -281 -200h331l-16 
-100h-334c0 -36 8 -68 19 -100h297l-16 -100h-222c55 -61 133 -100 222 -100c78 0 147 30 200 78v-122c-59 -35 -127 
-56 -200 -56c-147 0 -274 82 -344 200h-256
+l19 100h197c-8 32 -16 66 -16 100h-200l25 100h191c45 172 198 300 384 300z" />
+    <glyph glyph-name="5f" unicode="&#xe05f;" 
+d="M0 700h700v-100h-700v100zM0 500h500v-100h-500v100zM0 300h800v-100h-800v100zM0 100h100v-100h-100v100zM200 
100h100v-100h-100v100zM400 100h100v-100h-100v100z" />
+    <glyph glyph-name="60" unicode="&#xe060;" 
+d="M0 800h800v-100h-800v100zM200 600h400l-200 -200zM0 200h800v-200h-800v200z" />
+    <glyph glyph-name="61" unicode="&#xe061;" 
+d="M0 800h100v-800h-100v800zM600 800h200v-800h-200v800zM200 600l200 -200l-200 -200v400z" />
+    <glyph glyph-name="62" unicode="&#xe062;" 
+d="M0 800h200v-800h-200v800zM700 800h100v-800h-100v800zM600 600v-400l-200 200z" />
+    <glyph glyph-name="63" unicode="&#xe063;" 
+d="M0 800h800v-200h-800v200zM400 400l200 -200h-400zM0 100h800v-100h-800v100z" />
+    <glyph glyph-name="64" unicode="&#xe064;" 
+d="M0 800h200v-100h-100v-600h600v100h100v-200h-800v800zM400 800h400v-400l-150 150l-250 -250l-100 100l250 
250z" />
+    <glyph glyph-name="65" unicode="&#xe065;" 
+d="M403 700c247 0 397 -300 397 -300s-150 -300 -397 -300c-253 0 -403 300 -403 300s150 300 403 300zM400 
600c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200zM400 500c10 0 19 -3 28 -6c-16 
-8 -28 -24 -28 -44c0 -28 22 -50 50 -50
+c20 0 36 12 44 28c3 -9 6 -18 6 -28c0 -55 -45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
+    <glyph glyph-name="66" unicode="&#xe066;" horiz-adv-x="900" 
+d="M331 700h3h3c3 1 7 1 10 1c12 0 29 -8 37 -17l94 -93l66 65c57 57 155 57 212 0c58 -58 58 -154 0 -212l-65 
-66l93 -94c10 -8 18 -25 18 -38c0 -28 -22 -50 -50 -50c-13 0 -32 9 -40 20l-62 65l-381 -381h-269v272l375 381l-63 
63c-9 8 -16 24 -16 36c0 20 16 42 35 48z
+M447 481l-313 -315l128 -132l316 316z" />
+    <glyph glyph-name="67" unicode="&#xe067;" 
+d="M0 800h300v-400h400v-400h-700v800zM400 800l300 -300h-300v300z" />
+    <glyph glyph-name="68" unicode="&#xe068;" 
+d="M200 800c0 0 200 -100 200 -300s-298 -302 -200 -500c0 0 -200 100 -200 300s300 300 200 500zM500 500c0 0 200 
-100 200 -300c0 -150 -60 -200 -100 -200h-300c0 200 300 300 200 500z" />
+    <glyph glyph-name="69" unicode="&#xe069;" 
+d="M0 800h100v-800h-100v800zM200 800h300v-100h300l-200 -203l200 -197h-400v100h-200v400z" />
+    <glyph glyph-name="6a" unicode="&#xe06a;" horiz-adv-x="400" 
+d="M150 800h150l-100 -200h200l-150 -300h150l-300 -300l-100 300h134l66 200h-200z" />
+    <glyph glyph-name="6b" unicode="&#xe06b;" 
+d="M0 800h300v-100h500v-100h-800v200zM0 500h800v-450c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 50v450z" />
+    <glyph glyph-name="6c" unicode="&#xe06c;" 
+d="M150 800c83 0 150 -67 150 -150c0 -66 -41 -121 -100 -141v-118c15 5 33 9 50 9h200c28 0 50 22 50 50v59c-59 
20 -100 75 -100 141c0 83 67 150 150 150s150 -67 150 -150c0 -66 -41 -121 -100 -141v-59c0 -82 -68 -150 -150 
-150h-200c-14 0 -25 -7 -34 -16
+c50 -24 84 -74 84 -134c0 -83 -67 -150 -150 -150s-150 67 -150 150c0 66 41 121 100 141v218c-59 20 -100 75 -100 
141c0 83 67 150 150 150z" />
+    <glyph glyph-name="6d" unicode="&#xe06d;" 
+d="M0 800h400l-150 -150l150 -150l-100 -100l-150 150l-150 -150v400zM500 400l150 -150l150 150v-400h-400l150 
150l-150 150z" />
+    <glyph glyph-name="6e" unicode="&#xe06e;" 
+d="M100 800l150 -150l150 150v-400h-400l150 150l-150 150zM400 400h400l-150 -150l150 -150l-100 -100l-150 
150l-150 -150v400z" />
+    <glyph glyph-name="6f" unicode="&#xe06f;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM400 700c-56 0 
-108 -17 -153 -44l22 -19c33 -18 13 -48 -13 -59c-30 -13 -77 10 -65 -41c13 -55 -27 -3 -47 -15c-42 -26 49 -152 
31 -156l-59 34c-8 0 -13 -5 -16 -10
+c1 -30 10 -57 19 -84c28 -11 77 -2 100 -25c47 -28 97 -115 75 -159c34 -13 68 -22 106 -22c101 0 193 48 247 
125c3 24 -8 44 -50 44c-69 0 -156 13 -153 97c2 46 101 108 66 143c-30 30 12 39 12 66c0 37 -65 32 -69 50s20 36 
41 56c-30 10 -60 19 -94 19zM631 591
+c-38 -11 -94 -35 -87 -53c6 -15 52 -1 65 -13c11 -10 16 -59 44 -31l22 22v3c-11 26 -26 50 -44 72z" />
+    <glyph glyph-name="70" unicode="&#xe070;" 
+d="M703 800l97 -100l-400 -400l-100 100l-200 -203l-100 100l300 303l100 -100zM0 100h800v-100h-800v100z" />
+    <glyph glyph-name="71" unicode="&#xe071;" 
+d="M0 700h100v-100h-100v100zM200 700h100v-100h-100v100zM400 700h100v-100h-100v100zM600 
700h100v-100h-100v100zM0 500h100v-100h-100v100zM200 500h100v-100h-100v100zM400 500h100v-100h-100v100zM600 
500h100v-100h-100v100zM0 300h100v-100h-100v100zM200 300h100
+v-100h-100v100zM400 300h100v-100h-100v100zM600 300h100v-100h-100v100zM0 100h100v-100h-100v100zM200 
100h100v-100h-100v100zM400 100h100v-100h-100v100zM600 100h100v-100h-100v100z" />
+    <glyph glyph-name="72" unicode="&#xe072;" 
+d="M0 800h200v-200h-200v200zM300 800h200v-200h-200v200zM600 800h200v-200h-200v200zM0 
500h200v-200h-200v200zM300 500h200v-200h-200v200zM600 500h200v-200h-200v200zM0 200h200v-200h-200v200zM300 
200h200v-200h-200v200zM600 200h200v-200h-200v200z" />
+    <glyph glyph-name="73" unicode="&#xe073;" 
+d="M0 800h300v-300h-300v300zM500 800h300v-300h-300v300zM0 300h300v-300h-300v300zM500 300h300v-300h-300v300z" 
/>
+    <glyph glyph-name="74" unicode="&#xe074;" 
+d="M19 800h662c11 0 19 -8 19 -19v-331c0 -28 -22 -50 -50 -50h-600c-28 0 -50 22 -50 50v331c0 11 8 19 19 19zM0 
309c16 -6 32 -9 50 -9h600c18 0 34 3 50 9v-290c0 -11 -8 -19 -19 -19h-662c-11 0 -19 8 -19 19v290zM550 200c-28 0 
-50 -22 -50 -50s22 -50 50 -50
+s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="75" unicode="&#xe075;" 
+d="M0 700h300v-100h-50c-28 0 -50 -22 -50 -50v-150h300v150c0 28 -22 50 -50 50h-50v100h300v-100h-50c-28 0 -50 
-22 -50 -50v-400c0 -28 22 -50 50 -50h50v-100h-300v100h50c28 0 50 22 50 50v150h-300v-150c0 -28 22 -50 50 
-50h50v-100h-300v100h50c28 0 50 22 50 50
+v400c0 28 -22 50 -50 50h-50v100z" />
+    <glyph glyph-name="76" unicode="&#xe076;" 
+d="M400 700c165 0 300 -135 300 -300v-100h50c28 0 50 -22 50 -50v-200c0 -28 -22 -50 -50 -50h-100c-28 0 -50 22 
-50 50v350c0 111 -89 200 -200 200s-200 -89 -200 -200v-350c0 -28 -22 -50 -50 -50h-100c-28 0 -50 22 -50 
50v200c0 28 22 50 50 50h50v100
+c0 165 135 300 300 300z" />
+    <glyph glyph-name="77" unicode="&#xe077;" 
+d="M0 500c0 109 91 200 200 200s200 -91 200 -200c0 109 91 200 200 200s200 -91 200 -200c0 -55 -23 -105 -59 
-141l-341 -340l-341 340c-36 36 -59 86 -59 141z" />
+    <glyph glyph-name="78" unicode="&#xe078;" 
+d="M400 700l400 -300l-100 3v-403h-200v200h-200v-200h-200v400h-100z" />
+    <glyph glyph-name="79" unicode="&#xe079;" 
+d="M0 800h800v-800h-800v800zM100 700v-300l100 100l400 -400h100v100l-200 200l100 100l100 -100v300h-600z" />
+    <glyph glyph-name="7a" unicode="&#xe07a;" 
+d="M19 800h762c11 0 19 -8 19 -19v-762c0 -11 -8 -19 -19 -19h-762c-11 0 -19 8 -19 19v762c0 11 8 19 19 19zM100 
600v-300h100l100 -100h200l100 100h100v300h-600z" />
+    <glyph glyph-name="7b" unicode="&#xe07b;" 
+d="M200 600c80 0 142 -56 200 -122c58 66 119 122 200 122c131 0 200 -101 200 -200s-69 -200 -200 -200c-81 0 
-142 56 -200 122c-58 -66 -121 -122 -200 -122c-131 0 -200 101 -200 200s69 200 200 200zM200 500c-74 0 -100 -54 
-100 -100s26 -100 100 -100
+c42 0 88 47 134 100c-46 53 -92 100 -134 100zM600 500c-43 0 -88 -47 -134 -100c46 -53 91 -100 134 -100c74 0 
100 54 100 100s-26 100 -100 100z" />
+    <glyph glyph-name="7c" unicode="&#xe07c;" horiz-adv-x="400" 
+d="M300 800c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100zM150 550c83 0 150 -69 
150 -150c0 -66 -100 -214 -100 -250c0 -28 22 -50 50 -50s50 22 50 50h100c0 -83 -67 -150 -150 -150s-150 64 -150 
150s100 222 100 250s-22 50 -50 50
+s-50 -22 -50 -50h-100c0 83 67 150 150 150z" />
+    <glyph glyph-name="7d" unicode="&#xe07d;" 
+d="M200 800h500v-100h-122c-77 -197 -156 -392 -234 -588l-6 -12h162v-100h-500v100h122c77 197 156 392 234 588l7 
12h-163v100z" />
+    <glyph glyph-name="7e" unicode="&#xe07e;" 
+d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM100 100h600v-100h-600v100z" />
+    <glyph glyph-name="7f" unicode="&#xe07f;" 
+d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM0 100h600v-100h-600v100z" />
+    <glyph glyph-name="80" unicode="&#xe080;" 
+d="M0 700h800v-100h-800v100zM0 500h800v-100h-800v100zM0 300h800v-100h-800v100zM200 100h600v-100h-600v100z" />
+    <glyph glyph-name="81" unicode="&#xe081;" 
+d="M550 800c138 0 250 -112 250 -250s-112 -250 -250 -250c-16 0 -32 0 -47 3l-3 -3v-100h-200v-200h-300v200l303 
303c-3 15 -3 31 -3 47c0 138 112 250 250 250zM600 700c-55 0 -100 -45 -100 -100s45 -100 100 -100s100 45 100 
100s-45 100 -100 100z" />
+    <glyph glyph-name="82" unicode="&#xe082;" 
+d="M134 600h3h4h4h5h500c28 0 50 -22 50 -50v-350h100v-150c0 -28 -22 -50 -50 -50h-700c-28 0 -50 22 -50 
50v150h100v350v2c0 20 15 42 34 48zM200 500v-300h100v-100h200v100h100v300h-400z" />
+    <glyph glyph-name="83" unicode="&#xe083;" 
+d="M0 800h400v-400h-400v400zM500 600h100v-400h-400v100h300v300zM700 400h100v-400h-400v100h300v300z" />
+    <glyph glyph-name="84" unicode="&#xe084;" horiz-adv-x="600" 
+d="M337 694c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-300 -150c-8 -6 -21 -11 -31 -11c-28 0 -50 
22 -50 50c0 21 16 44 37 49zM437 544c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-400 -200c-8 -6 
-21 -11 -31 -11c-28 0 -50 22 -50 50
+c0 21 16 44 37 49zM437 344c6 4 12 7 21 7c28 0 50 -22 50 -50c0 -17 -12 -37 -27 -45l-106 -56c24 -4 43 -26 43 
-50c0 -28 -23 -51 -51 -51c-2 0 -6 1 -8 1h-200c-26 1 -48 24 -48 50c0 16 12 36 26 44zM151 -50c0 23 20 50 46 
50h3h4h5h100c28 0 50 -22 50 -50
+s-22 -50 -50 -50h-100c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 51z" />
+    <glyph glyph-name="85" unicode="&#xe085;" 
+d="M199 800h100v-200h-200v100h100v100zM586 797h1c18 1 38 1 56 -3c36 -8 69 -26 97 -54c78 -78 78 -203 0 
-281l-150 -150c-8 -13 -28 -24 -43 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43l150 150c40 40 39 105 0 144c-41 41 
-110 34 -144 0l-44 -44
+c-8 -13 -27 -24 -42 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43l43 44c32 33 72 53 128 56zM208 490c4 5 14 16 22 
16h3c2 0 6 1 8 1c28 0 50 -22 50 -50c0 -11 -6 -27 -14 -35l-150 -150c-40 -40 -39 -105 0 -144c41 -41 110 -34 144 
0l44 44c8 13 27 24 42 24
+c28 0 50 -22 50 -50c0 -15 -11 -35 -24 -43l-43 -44c-22 -22 -48 -37 -75 -47c-70 -25 -151 -9 -207 47c-78 78 -78 
203 0 281zM499 200h200v-100h-100v-100h-100v200z" />
+    <glyph glyph-name="86" unicode="&#xe086;" 
+d="M586 797c18 1 39 1 57 -3c36 -8 69 -26 97 -54c78 -78 78 -203 0 -281l-150 -150c-62 -62 -132 -81 -182 
-78s-69 17 -84 25s-26 27 -26 44c0 28 22 51 50 51c8 0 19 -3 26 -7c0 0 15 -11 41 -13s62 3 106 47l150 150c40 40 
39 105 0 144c-41 41 -110 34 -144 0
+c-8 -13 -28 -24 -43 -24c-28 0 -50 22 -50 50c0 15 11 35 24 43c32 33 72 53 128 56zM386 566c50 -2 64 -17 85 
-22s37 -28 37 -49c0 -28 -22 -50 -50 -50c-10 0 -23 5 -31 11c0 0 -19 9 -47 10s-63 -4 -103 -44l-150 -150c-40 -40 
-39 -105 0 -144c41 -41 110 -34 144 0
+c8 13 27 24 42 24c28 0 50 -22 50 -50c0 -15 -10 -35 -23 -43c-22 -22 -48 -37 -75 -47c-70 -25 -151 -9 -207 
47c-78 78 -78 203 0 281l150 150c60 60 128 78 178 76z" />
+    <glyph glyph-name="87" unicode="&#xe087;" 
+d="M0 700h300v-300h-300v300zM400 700h400v-100h-400v100zM400 500h300v-100h-300v100zM0 
300h300v-300h-300v300zM400 300h400v-100h-400v100zM400 100h300v-100h-300v100z" />
+    <glyph glyph-name="88" unicode="&#xe088;" 
+d="M50 700c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM200 700h600v-100h-600v100zM50 
500c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM200 500h600v-100h-600v100zM50 300c28 0 50 
-22 50 -50s-22 -50 -50 -50s-50 22 -50 50
+s22 50 50 50zM200 300h600v-100h-600v100zM50 100c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 
50zM200 100h600v-100h-600v100z" />
+    <glyph glyph-name="89" unicode="&#xe089;" 
+d="M800 800l-400 -800l-100 300l-300 100z" />
+    <glyph glyph-name="8a" unicode="&#xe08a;" horiz-adv-x="600" 
+d="M300 700c110 0 200 -90 200 -200v-100h100v-400h-600v400h100v100c0 110 90 200 200 200zM300 600c-56 0 -100 
-44 -100 -100v-100h200v100c0 56 -44 100 -100 100z" />
+    <glyph glyph-name="8b" unicode="&#xe08b;" horiz-adv-x="600" 
+d="M300 800c110 0 200 -90 200 -200v-200h100v-400h-600v400h400v200c0 56 -44 100 -100 100s-100 -44 -100 
-100h-100c0 110 90 200 200 200z" />
+    <glyph glyph-name="8c" unicode="&#xe08c;" 
+d="M400 700v-100c-111 0 -200 -89 -200 -200h100l-150 -200l-150 200h100c0 165 135 300 300 300zM650 600l150 
-200h-100c0 -165 -135 -300 -300 -300v100c111 0 200 89 200 200h-100z" />
+    <glyph glyph-name="8d" unicode="&#xe08d;" 
+d="M100 800h600v-300h100l-150 -250l-150 250h100v200h-400v-100h-100v200zM150 550l150 
-250h-100v-200h400v100h100v-200h-600v300h-100z" />
+    <glyph glyph-name="8e" unicode="&#xe08e;" 
+d="M600 700l200 -150l-200 -150v100h-500v-100h-100v100c0 55 45 100 100 100h500v100zM200 
300v-100h500v100h100v-100c0 -55 -45 -100 -100 -100h-500v-100l-200 150z" />
+    <glyph glyph-name="8f" unicode="&#xe08f;" horiz-adv-x="900" 
+d="M350 800c193 0 350 -157 350 -350c0 -60 -17 -117 -44 -166c5 -3 12 -8 16 -12l100 -100c16 -16 30 -49 30 
-72c0 -56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 100c-4 3 -9 9 -12 13c-49 -26 -107 -41 -166 -41c-193 0 
-350 157 -350 350s157 350 350 350zM350 200
+c142 0 250 108 250 250c0 139 -111 250 -250 250s-250 -111 -250 -250s111 -250 250 -250z" />
+    <glyph glyph-name="90" unicode="&#xe090;" horiz-adv-x="600" 
+d="M300 800c166 0 300 -134 300 -300c0 -200 -300 -500 -300 -500s-300 300 -300 500c0 166 134 300 300 300zM300 
700c-110 0 -200 -90 -200 -200s90 -200 200 -200s200 90 200 200s-90 200 -200 200z" />
+    <glyph glyph-name="91" unicode="&#xe091;" horiz-adv-x="900" 
+d="M0 800h800v-541c1 -3 1 -8 1 -11s0 -7 -1 -10v-238h-800v800zM495 250c0 26 22 50 50 
50h5h150v400h-600v-600h600v100h-150h-5c-28 0 -50 22 -50 50zM350 600c83 0 150 -67 150 -150c0 -100 -150 -250 
-150 -250s-150 150 -150 250c0 83 67 150 150 150zM350 500
+c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="92" unicode="&#xe092;" horiz-adv-x="600" 
+d="M0 700h200v-600h-200v600zM400 700h200v-600h-200v600z" />
+    <glyph glyph-name="93" unicode="&#xe093;" horiz-adv-x="600" 
+d="M0 700l600 -300l-600 -300v600z" />
+    <glyph glyph-name="94" unicode="&#xe094;" horiz-adv-x="600" 
+d="M300 700c166 0 300 -134 300 -300s-134 -300 -300 -300s-300 134 -300 300s134 300 300 300z" />
+    <glyph glyph-name="95" unicode="&#xe095;" 
+d="M400 700v-600l-400 300zM400 400l400 300v-600z" />
+    <glyph glyph-name="96" unicode="&#xe096;" 
+d="M0 700l400 -300l-400 -300v600zM400 100v600l400 -300z" />
+    <glyph glyph-name="97" unicode="&#xe097;" 
+d="M0 700h200v-600h-200v600zM200 400l500 300v-600z" />
+    <glyph glyph-name="98" unicode="&#xe098;" 
+d="M0 700l500 -300l-500 -300v600zM500 100v600h200v-600h-200z" />
+    <glyph glyph-name="99" unicode="&#xe099;" horiz-adv-x="600" 
+d="M0 700h600v-600h-600v600z" />
+    <glyph glyph-name="9a" unicode="&#xe09a;" 
+d="M200 800h400v-200h200v-400h-200v-200h-400v200h-200v400h200v200z" />
+    <glyph glyph-name="9b" unicode="&#xe09b;" 
+d="M0 700h800v-100h-800v100zM0 403h800v-100h-800v100zM0 103h800v-100h-800v100z" />
+    <glyph glyph-name="9c" unicode="&#xe09c;" horiz-adv-x="600" 
+d="M278 700c7 2 13 4 22 4c55 0 100 -45 100 -100v-4v-200c0 -55 -45 -100 -100 -100s-100 45 -100 100v200v2c0 44 
35 88 78 98zM34 500h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-50c0 -111 89 -200 200 -200s200 89 200 200v50c0 28 
22 50 50 50s50 -22 50 -50v-50
+c0 -148 -109 -270 -250 -294v-106h50c55 0 100 -45 100 -100h-400c0 55 45 100 100 100h50v106c-141 24 -250 146 
-250 294v50v2c0 20 15 42 34 48z" />
+    <glyph glyph-name="9d" unicode="&#xe09d;" 
+d="M0 500h800v-200h-800v200z" />
+    <glyph glyph-name="9e" unicode="&#xe09e;" 
+d="M34 700h4h3h4h5h700c28 0 50 -22 50 -50v-500c0 -28 -22 -50 -50 -50h-250v-100h100c55 0 100 -45 100 
-100h-600c0 55 45 100 100 100h100v100h-250c-28 0 -50 22 -50 50v500v2c0 20 15 42 34 48zM100 
600v-400h600v400h-600z" />
+    <glyph glyph-name="9f" unicode="&#xe09f;" 
+d="M272 700c-14 -40 -22 -83 -22 -128c0 -221 179 -400 400 -400c45 0 88 8 128 22c-53 -158 -202 -272 -378 
-272c-221 0 -400 179 -400 400c0 176 114 325 272 378z" />
+    <glyph glyph-name="a0" unicode="&#xe0a0;" 
+d="M350 700l150 -150h-100v-150h150v100l150 -150l-150 -150v100h-150v-150h100l-150 -150l-150 
150h100v150h-150v-100l-150 150l150 150v-100h150v150h-100z" />
+    <glyph glyph-name="a1" unicode="&#xe0a1;" 
+d="M800 800v-550c0 -83 -67 -150 -150 -150s-150 67 -150 150s67 150 150 150c17 0 35 -4 50 -9v206c-201 -6 -327 
-27 -400 -50v-397c0 -83 -67 -150 -150 -150s-150 67 -150 150s67 150 150 150c17 0 35 -4 50 -9v409s100 100 600 
100z" />
+    <glyph glyph-name="a2" unicode="&#xe0a2;" horiz-adv-x="700" 
+d="M499 700c51 0 102 -20 141 -59c78 -78 78 -203 0 -281l-250 -244c-48 -48 -127 -48 -175 0s-48 127 0 175l96 
97l69 -69l-90 -94l-7 -3c-10 -10 -10 -28 0 -38s28 -10 38 0l250 247c37 40 39 102 0 141s-104 40 -144 0l-278 
-275c-66 -69 -68 -179 0 -247
+c69 -69 181 -69 250 0l9 12l116 113l69 -69l-125 -125c-107 -107 -281 -107 -388 0s-107 281 0 388l278 272c39 39 
90 59 141 59z" />
+    <glyph glyph-name="a3" unicode="&#xe0a3;" 
+d="M600 800l200 -200l-100 -100l-200 200zM400 600l200 -200l-400 -400h-200v200z" />
+    <glyph glyph-name="a4" unicode="&#xe0a4;" 
+d="M550 800c83 0 150 -90 150 -200s-67 -200 -150 -200c-22 0 -40 8 -59 19c6 26 9 52 9 81c0 84 -27 158 -72 
212c27 52 71 88 122 88zM250 700c83 0 150 -90 150 -200s-67 -200 -150 -200s-150 90 -150 200s67 200 150 200zM725 
384c44 -22 75 -66 75 -118v-166h-200v66
+c0 50 -17 96 -44 134c66 2 126 33 169 84zM75 284c45 -53 106 -84 175 -84s130 31 175 84c44 -22 75 -66 75 
-118v-166h-500v166c0 52 31 96 75 118z" />
+    <glyph glyph-name="a5" unicode="&#xe0a5;" 
+d="M400 800c110 0 200 -112 200 -250s-90 -250 -200 -250s-200 112 -200 250s90 250 200 250zM191 300c54 -61 128 
-100 209 -100s155 39 209 100c106 -5 191 -92 191 -200v-100h-800v100c0 108 85 195 191 200z" />
+    <glyph glyph-name="a6" unicode="&#xe0a6;" horiz-adv-x="600" 
+d="M19 800h462c11 0 19 -8 19 -19v-762c0 -11 -8 -19 -19 -19h-462c-11 0 -19 8 -19 19v762c0 11 8 19 19 19zM100 
700v-500h300v500h-300zM250 150c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="a7" unicode="&#xe0a7;" 
+d="M350 800c17 0 34 -1 50 -3v-397l-297 297c63 64 150 103 247 103zM500 694c169 -25 300 -168 300 -344c0 -193 
-157 -350 -350 -350c-85 0 -161 31 -222 81l272 272v341zM91 562l237 -234l-212 -212c-70 55 -116 138 -116 234c0 
84 35 158 91 212z" />
+    <glyph glyph-name="a8" unicode="&#xe0a8;" 
+d="M92 650c0 23 20 50 46 50h3h4h5h400c28 0 50 -22 50 -50s-22 -50 -50 -50h-50v-200h100c55 0 100 -45 100 
-100h-300v-300l-56 -100l-44 100v300h-300c0 55 45 100 100 100h100v200h-50c-2 0 -6 -1 -8 -1c-28 0 -50 23 -50 
51z" />
+    <glyph glyph-name="a9" unicode="&#xe0a9;" 
+d="M400 800c221 0 400 -179 400 -400s-179 -400 -400 -400s-400 179 -400 400s179 400 400 400zM300 600v-400l300 
200z" />
+    <glyph glyph-name="aa" unicode="&#xe0aa;" 
+d="M300 800h200v-300h300v-200h-300v-300h-200v300h-300v200h300v300z" />
+    <glyph glyph-name="ab" unicode="&#xe0ab;" 
+d="M300 800h100v-400h-100v400zM172 656l62 -78l-40 -31c-58 -46 -94 -117 -94 -197c0 -139 111 -250 250 -250s250 
111 250 250c0 80 -39 151 -97 197l-37 31l62 78l38 -31c82 -64 134 -164 134 -275c0 -193 -157 -350 -350 -350s-350 
157 -350 350c0 111 53 211 134 275z
+" />
+    <glyph glyph-name="ac" unicode="&#xe0ac;" 
+d="M200 800h400v-200h-400v200zM9 500h782c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 -9h-91v200h-600v-200h-91c-6 0 -9 3 
-9 9v282c0 6 3 9 9 9zM200 300h400v-300h-400v300z" />
+    <glyph glyph-name="ad" unicode="&#xe0ad;" 
+d="M0 700h100v-700h-100v700zM700 700h100v-700h-100v700zM200 600h200v-100h-200v100zM300 
400h200v-100h-200v100zM400 200h200v-100h-200v100z" />
+    <glyph glyph-name="ae" unicode="&#xe0ae;" 
+d="M325 700c42 -141 87 -280 131 -419c29 74 59 148 88 222c30 -57 58 -114 87 -172h169v-100h-231l-13 28c-37 -92 
-74 -184 -112 -275c-38 129 -79 257 -119 385c-42 -133 -83 -267 -125 -400c-28 88 -56 175 -84 262h-116v100h188l9 
-34l3 -6c42 137 83 273 125 409z" />
+    <glyph glyph-name="af" unicode="&#xe0af;" 
+d="M200 600c0 57 43 100 100 100s100 -43 100 -100c0 -28 -18 -48 -28 -72c-3 -6 -3 -16 -3 -28h231v-231c12 0 22 
0 28 3c24 10 44 28 72 28c57 0 100 -43 100 -100s-43 -100 -100 -100c-28 0 -48 18 -72 28c-6 3 -16 3 -28 
3v-231h-231c0 12 0 22 3 28c10 24 28 44 28 72
+c0 57 -43 100 -100 100s-100 -43 -100 -100c0 -28 18 -48 28 -72c3 -6 3 -16 3 -28h-231v600h231c0 12 0 22 -3 
28c-10 24 -28 44 -28 72z" />
+    <glyph glyph-name="b0" unicode="&#xe0b0;" horiz-adv-x="500" 
+d="M247 700c84 0 148 -20 191 -59s59 -93 59 -141c0 -117 -69 -181 -119 -225s-81 -67 -81 -150v-25h-100v25c0 117 
65 181 115 225s85 67 85 150c0 25 -8 48 -28 66s-56 34 -122 34s-97 -18 -116 -37s-27 -43 -31 -69l-100 12c5 38 19 
88 59 128s103 66 188 66zM197 0h100
+v-100h-100v100z" />
+    <glyph glyph-name="b1" unicode="&#xe0b1;" 
+d="M450 800c138 0 250 -112 250 -250v-50c58 -21 100 -85 100 -150c0 -69 -48 -127 -112 -144c-22 55 -75 94 -138 
94c-20 0 -39 -5 -56 -12c-17 64 -75 112 -144 112s-127 -48 -144 -112c-17 7 -36 12 -56 12c-37 0 -71 -12 -97 
-34c-33 36 -53 82 -53 134
+c0 110 90 200 200 200c23 114 129 200 250 200zM334 300h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-200c0 -28 -22 
-50 -50 -50s-50 22 -50 50v200v2c0 20 15 42 34 48zM134 200h4h3c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-100c0 -28 
-22 -50 -50 -50s-50 22 -50 50v100v2
+c0 20 15 42 34 48zM534 200h3h4c3 0 6 1 9 1c28 0 50 -22 50 -50v-1v-100c0 -28 -22 -50 -50 -50s-50 22 -50 
50v100v2c0 20 15 42 34 48z" />
+    <glyph glyph-name="b2" unicode="&#xe0b2;" 
+d="M600 800l200 -150l-200 -150v100h-50l-153 -191l175 -206l6 -3h22v100l200 -150l-200 -150v100h-25c-35 0 -56 
12 -78 38l-166 190l-153 -190c-22 -27 -43 -38 -78 -38h-100v100h100l166 206l-163 191l-3 3h-100v100h100c34 0 56 
-12 78 -38l153 -178l141 178
+c22 27 43 38 78 38h50v100z" />
+    <glyph glyph-name="b3" unicode="&#xe0b3;" 
+d="M400 800c110 0 209 -47 281 -119l119 119v-300h-300l109 109c-54 55 -126 91 -209 91c-166 0 -300 -134 -300 
-300s134 -300 300 -300c83 0 158 34 212 88l72 -72c-72 -72 -174 -116 -284 -116c-220 0 -400 180 -400 400s180 400 
400 400z" />
+    <glyph glyph-name="b4" unicode="&#xe0b4;" 
+d="M400 800h400v-400l-166 166l-400 -400l166 -166h-400v400l166 -166l400 400z" />
+    <glyph glyph-name="b5" unicode="&#xe0b5;" horiz-adv-x="600" 
+d="M250 800l250 -300h-200v-200h200l-250 -300l-250 300h200v200h-200z" />
+    <glyph glyph-name="b6" unicode="&#xe0b6;" 
+d="M300 600v-200h200v200l300 -250l-300 -250v200h-200v-200l-300 250z" />
+    <glyph glyph-name="b7" unicode="&#xe0b7;" 
+d="M0 800c441 0 800 -359 800 -800h-200c0 333 -267 600 -600 600v200zM0 500c275 0 500 -225 500 -500h-200c0 167 
-133 300 -300 300v200zM0 200c110 0 200 -90 200 -200h-200v200z" />
+    <glyph glyph-name="b8" unicode="&#xe0b8;" 
+d="M100 800c386 0 700 -314 700 -700h-100c0 332 -268 600 -600 600v100zM100 600c276 0 500 -224 500 -500h-100c0 
222 -178 400 -400 400v100zM100 400c165 0 300 -135 300 -300h-100c0 111 -89 200 -200 200v100zM100 200c55 0 100 
-45 100 -100s-45 -100 -100 -100
+s-100 45 -100 100s45 100 100 100z" />
+    <glyph glyph-name="b9" unicode="&#xe0b9;" 
+d="M300 800h400c55 0 100 -45 100 -100v-200h-400v150c0 28 -22 50 -50 50s-50 -22 -50 -50v-250h400v-300c0 -55 
-45 -100 -100 -100h-500c-55 0 -100 45 -100 100v200h100v-150c0 -28 22 -50 50 -50s50 22 50 50v550c0 55 45 100 
100 100z" />
+    <glyph glyph-name="ba" unicode="&#xe0ba;" 
+d="M75 700h225v-100h-200v-500h400v100h100v-125c0 -41 -34 -75 -75 -75h-450c-41 0 -75 34 -75 75v550c0 41 34 75 
75 75zM600 700l200 -200l-200 -200v100h-200c-94 0 -173 -65 -194 -153c23 199 189 353 394 353v100z" />
+    <glyph glyph-name="bb" unicode="&#xe0bb;" 
+d="M500 700l300 -284l-300 -316v200h-100c-200 0 -348 -102 -400 -300c0 295 100 500 500 500v200z" />
+    <glyph glyph-name="bc" unicode="&#xe0bc;" 
+d="M381 791l19 9l19 -9c127 -53 253 -108 381 -160v-31c0 -166 -67 -313 -147 -419c-40 -53 -83 -97 -125 -128s-82 
-53 -128 -53s-86 22 -128 53s-85 75 -125 128c-80 107 -147 253 -147 419v31c128 52 254 107 381 160zM400 
100v591l-294 -122c8 -126 58 -243 122 -328
+c35 -46 73 -86 106 -110s62 -31 66 -31z" />
+    <glyph glyph-name="bd" unicode="&#xe0bd;" 
+d="M600 800h100v-800h-100v800zM400 700h100v-700h-100v700zM200 500h100v-500h-100v500zM0 
300h100v-300h-100v300z" />
+    <glyph glyph-name="be" unicode="&#xe0be;" 
+d="M300 800h100v-200h200l100 -100l-100 -100h-200v-400h-100v500h-200l-100 100l100 100h200v100z" />
+    <glyph glyph-name="bf" unicode="&#xe0bf;" 
+d="M200 800h100v-600h200l-250 -200l-250 200h200v600zM400 800h200v-100h-200v100zM400 
600h300v-100h-300v100zM400 400h400v-100h-400v100z" />
+    <glyph glyph-name="c0" unicode="&#xe0c0;" 
+d="M200 800h100v-600h200l-250 -200l-250 200h200v600zM400 800h400v-100h-400v100zM400 
600h300v-100h-300v100zM400 400h200v-100h-200v100z" />
+    <glyph glyph-name="c1" unicode="&#xe0c1;" 
+d="M75 700h650c41 0 75 -34 75 -75v-550c0 -41 -34 -75 -75 -75h-650c-41 0 -75 34 -75 75v550c0 41 34 75 75 
75zM100 600v-100h100v100h-100zM300 600v-100h400v100h-400zM100 400v-100h100v100h-100zM300 
400v-100h400v100h-400zM100 200v-100h100v100h-100zM300 200
+v-100h400v100h-400z" />
+    <glyph glyph-name="c2" unicode="&#xe0c2;" 
+d="M400 800l100 -300h300l-250 -200l100 -300l-250 200l-250 -200l100 300l-250 200h300z" />
+    <glyph glyph-name="c3" unicode="&#xe0c3;" 
+d="M400 800c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM150 700c28 0 50 -22 50 -50s-22 -50 
-50 -50s-50 22 -50 50s22 50 50 50zM650 700c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM400 
600c110 0 200 -90 200 -200
+s-90 -200 -200 -200s-200 90 -200 200s90 200 200 200zM50 450c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 
50s22 50 50 50zM750 450c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM150 200c28 0 50 -22 50 
-50s-22 -50 -50 -50s-50 22 -50 50
+s22 50 50 50zM650 200c28 0 50 -22 50 -50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50zM400 100c28 0 50 -22 50 
-50s-22 -50 -50 -50s-50 22 -50 50s22 50 50 50z" />
+    <glyph glyph-name="c4" unicode="&#xe0c4;" 
+d="M34 800h632c18 0 34 -16 34 -34v-732c0 -18 -16 -34 -34 -34h-632c-18 0 -34 16 -34 34v732c0 18 16 34 34 
34zM100 700v-500h500v500h-500zM350 150c-38 0 -63 -42 -44 -75s69 -33 88 0s-6 75 -44 75z" />
+    <glyph glyph-name="c5" unicode="&#xe0c5;" 
+d="M0 800h300l500 -500l-300 -300l-500 500v300zM200 700c-55 0 -100 -45 -100 -100s45 -100 100 -100s100 45 100 
100s-45 100 -100 100z" />
+    <glyph glyph-name="c6" unicode="&#xe0c6;" 
+d="M0 600h200l300 -300l-200 -200l-300 300v200zM340 600h160l300 -300l-200 -200l-78 78l119 122zM150 500c-28 0 
-50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="c7" unicode="&#xe0c7;" 
+d="M400 800c220 0 400 -180 400 -400s-180 -400 -400 -400s-400 180 -400 400s180 400 400 400zM400 700c-166 0 
-300 -134 -300 -300s134 -300 300 -300s300 134 300 300s-134 300 -300 300zM400 600c110 0 200 -90 200 -200s-90 
-200 -200 -200s-200 90 -200 200
+s90 200 200 200zM400 500c-56 0 -100 -44 -100 -100s44 -100 100 -100s100 44 100 100s-44 100 -100 100z" />
+    <glyph glyph-name="c8" unicode="&#xe0c8;" 
+d="M0 700h559l-100 -100h-359v-500h500v159l100 100v-359h-700v700zM700 700l100 -100l-400 -400l-200 200l100 
100l100 -100z" />
+    <glyph glyph-name="c9" unicode="&#xe0c9;" 
+d="M9 800h782c6 0 9 -3 9 -9v-782c0 -6 -3 -9 -9 -9h-782c-6 0 -9 3 -9 9v782c0 6 3 9 9 9zM150 722l-72 -72l100 
-100l-100 -100l72 -72l172 172zM400 500v-100h300v100h-300z" />
+    <glyph glyph-name="ca" unicode="&#xe0ca;" 
+d="M0 800h800v-200h-50c0 55 -45 100 -100 100h-150v-550c0 -28 22 -50 50 -50h50v-100h-400v100h50c28 0 50 22 50 
50v550h-150c-55 0 -100 -45 -100 -100h-50v200z" />
+    <glyph glyph-name="cb" unicode="&#xe0cb;" 
+d="M0 700h100v-400h-100v400zM200 700h350c21 0 39 -13 47 -31c0 0 103 -291 103 -319s-22 -50 -50 -50h-150c-28 0 
-50 -25 -50 -50s39 -158 47 -184s-5 -55 -31 -63s-52 5 -66 31s-109 219 -128 238s-44 28 -72 28v400z" />
+    <glyph glyph-name="cc" unicode="&#xe0cc;" 
+d="M400 666c10 19 28 32 47 34l19 -3c26 -8 39 -37 31 -63s-47 -159 -47 -184s22 -50 50 -50h150c28 0 50 -22 50 
-50s-103 -319 -103 -319c-8 -18 -26 -31 -47 -31h-350v400c28 0 53 9 72 28s114 212 128 238zM0 
400h100v-400h-100v400z" />
+    <glyph glyph-name="cd" unicode="&#xe0cd;" 
+d="M200 700h300v-100h-100v-6c25 -4 50 -8 72 -16l-34 -94c-28 11 -58 16 -88 16c-139 0 -250 -111 -250 -250s111 
-250 250 -250s250 111 250 250c0 31 -5 60 -16 88l91 37c14 -38 25 -81 25 -125c0 -193 -157 -350 -350 -350s-350 
157 -350 350c0 176 130 323 300 347v3
+h-100v100zM700 584c0 0 -296 -348 -316 -368s-48 -20 -68 0s-20 48 0 68s384 300 384 300z" />
+    <glyph glyph-name="ce" unicode="&#xe0ce;" 
+d="M600 700l200 -150l-200 -150v100h-600v100h600v100zM200 300v-100h600v-100h-600v-100l-200 150z" />
+    <glyph glyph-name="cf" unicode="&#xe0cf;" 
+d="M300 800h100c55 0 100 -45 100 -100h100c55 0 100 -45 100 -100h-700c0 55 45 100 100 100h100c0 55 45 100 100 
100zM100 500h100v-350c0 -28 22 -50 50 -50s50 22 50 50v350h100v-350c0 -28 22 -50 50 -50s50 22 50 
50v350h100v-481c0 -11 -8 -19 -19 -19h-462
+c-11 0 -19 8 -19 19v481z" />
+    <glyph glyph-name="d0" unicode="&#xe0d0;" 
+d="M100 800h200v-400c0 -55 45 -100 100 -100s100 45 100 100v400h100v-400c0 -110 -90 -200 -200 -200h-50c-138 0 
-250 90 -250 200v400zM0 100h700v-100h-700v100z" />
+    <glyph glyph-name="d1" unicode="&#xe0d1;" 
+d="M9 700h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 9zM609 700h182c6 0 9 -3 
9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 9zM309 500h182c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 
-9h-182c-6 0 -9 3 -9 9v282
+c0 6 3 9 9 9zM0 100h800v-100h-800v100z" />
+    <glyph glyph-name="d2" unicode="&#xe0d2;" 
+d="M10 700h181c6 0 9 -3 9 -9v-191h-200v191c0 6 4 9 10 9zM610 700h181c6 0 9 -3 9 -9v-191h-200v191c0 6 5 9 10 
9zM310 600h181c6 0 9 -3 9 -9v-91h-200v91c0 6 4 9 10 9zM0 400h800v-100h-800v100zM0 200h200v-191c0 -6 -3 -9 -9 
-9h-182c-6 0 -9 3 -9 9v191zM300 200
+h200v-91c0 -6 -3 -9 -9 -9h-181c-6 0 -10 3 -10 9v91zM600 200h200v-191c0 -6 -3 -9 -9 -9h-181c-6 0 -10 3 -10 
9v191z" />
+    <glyph glyph-name="d3" unicode="&#xe0d3;" 
+d="M0 700h800v-100h-800v100zM9 500h182c6 0 9 -3 9 -9v-482c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v482c0 6 3 9 9 
9zM309 500h182c6 0 9 -3 9 -9v-282c0 -6 -3 -9 -9 -9h-182c-6 0 -9 3 -9 9v282c0 6 3 9 9 9zM609 500h182c6 0 9 -3 
9 -9v-482c0 -6 -3 -9 -9 -9h-182
+c-6 0 -9 3 -9 9v482c0 6 3 9 9 9z" />
+    <glyph glyph-name="d4" unicode="&#xe0d4;" 
+d="M50 600h500c28 0 50 -22 50 -50v-150l100 100h100v-300h-100l-100 100v-150c0 -28 -22 -50 -50 -50h-500c-28 0 
-50 22 -50 50v400c0 28 22 50 50 50z" />
+    <glyph glyph-name="d5" unicode="&#xe0d5;" 
+d="M334 800h66v-800h-66l-134 200h-200v400h200zM500 600v100c26 0 52 -4 75 -10c130 -33 225 -150 225 -290s-95 
-258 -225 -291h-3c-23 -6 -47 -9 -72 -9v100c17 0 34 2 50 6c86 22 150 100 150 194s-64 172 -150 194c-16 4 -33 6 
-50 6zM500 500l25 -3
+c44 -11 75 -51 75 -97s-32 -86 -75 -97l-25 -3v200z" />
+    <glyph glyph-name="d6" unicode="&#xe0d6;" horiz-adv-x="600" 
+d="M334 800h66v-800h-66l-134 200h-200v400h200zM500 500l25 -3c44 -11 75 -51 75 -97s-32 -86 -75 -97l-25 
-3v200z" />
+    <glyph glyph-name="d7" unicode="&#xe0d7;" horiz-adv-x="400" 
+d="M334 800h66v-800h-66l-134 200h-200v400h200z" />
+    <glyph glyph-name="d8" unicode="&#xe0d8;" 
+d="M309 800h82c6 0 10 -4 12 -9l294 -682l3 -19v-81c0 -6 -3 -9 -9 -9h-682c-6 0 -9 3 -9 9v81l3 19l294 682c2 5 6 
9 12 9zM300 500v-200h100v200h-100zM300 200v-100h100v100h-100z" />
+    <glyph glyph-name="d9" unicode="&#xe0d9;" 
+d="M375 800c138 0 269 -39 378 -109l-53 -82c-93 60 -205 91 -325 91c-119 0 -229 -32 -322 -91l-53 82c109 70 237 
109 375 109zM375 500c78 0 154 -23 216 -62l-53 -85c-46 30 -104 47 -163 47c-60 0 -112 -17 -159 -47l-54 85c62 40 
134 62 213 62zM375 200
+c55 0 100 -45 100 -100s-45 -100 -100 -100s-100 45 -100 100s45 100 100 100z" />
+    <glyph glyph-name="da" unicode="&#xe0da;" horiz-adv-x="900" 
+d="M551 800c16 0 32 0 47 -3l-97 -97v-200h200l97 97c3 -15 3 -31 3 -47c0 -138 -112 -250 -250 -250c-32 0 -62 8 
-90 19l-288 -291c-20 -20 -46 -28 -72 -28s-52 8 -72 28c-39 39 -39 105 0 144l291 287c-11 28 -19 59 -19 91c0 138 
112 250 250 250zM101 150
+c-28 0 -50 -22 -50 -50s22 -50 50 -50s50 22 50 50s-22 50 -50 50z" />
+    <glyph glyph-name="db" unicode="&#xe0db;" 
+d="M141 700c84 -84 169 -167 253 -250c82 83 167 165 247 250l143 -141l-253 -253c84 -82 167 -166 253 -247l-143 
-143c-81 86 -165 169 -247 253l-253 -253l-141 143c85 80 167 164 250 247c-83 84 -166 169 -250 253z" />
+    <glyph glyph-name="dc" unicode="&#xe0dc;" 
+d="M0 800h100l231 -300h38l231 300h100l-225 
-300h225v-100h-300v-100h300v-100h-300v-200h-100v200h-300v100h300v100h-300v100h225z" />
+    <glyph glyph-name="dd" unicode="&#xe0dd;" horiz-adv-x="900" 
+d="M350 800c193 0 350 -157 350 -350c0 -61 -17 -119 -44 -169c4 -2 10 -6 13 -9l103 -100c16 -16 30 -49 30 -72c0 
-56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 103c-3 3 -7 9 -9 13c-50 -28 -108 -44 -169 -44c-193 0 -350 157 
-350 350s157 350 350 350zM350 700
+c-139 0 -250 -111 -250 -250s111 -250 250 -250c62 0 119 23 163 60c7 11 19 25 31 31l3 3c34 43 53 97 53 156c0 
139 -111 250 -250 250zM300 600h100v-100h100v-100h-100v-100h-100v100h-100v100h100v100z" />
+    <glyph glyph-name="de" unicode="&#xe0de;" horiz-adv-x="900" 
+d="M350 800c193 0 350 -157 350 -350c0 -61 -17 -119 -44 -169c4 -2 10 -6 13 -9l103 -100c16 -16 30 -49 30 -72c0 
-56 -46 -102 -102 -102c-23 0 -56 14 -72 30l-100 103c-3 3 -7 9 -9 13c-50 -28 -108 -44 -169 -44c-193 0 -350 157 
-350 350s157 350 350 350zM350 700
+c-139 0 -250 -111 -250 -250s111 -250 250 -250c62 0 119 23 163 60c7 11 19 25 31 31l3 3c34 43 53 97 53 156c0 
139 -111 250 -250 250zM200 500h300v-100h-300v100z" />
+  </font>
+</defs></svg>
diff --git a/src/fonts/open-iconic.ttf b/src/fonts/open-iconic.ttf
new file mode 100644
index 0000000..fab6048
Binary files /dev/null and b/src/fonts/open-iconic.ttf differ
diff --git a/src/fonts/open-iconic.woff b/src/fonts/open-iconic.woff
new file mode 100644
index 0000000..f930998
Binary files /dev/null and b/src/fonts/open-iconic.woff differ
diff --git a/src/graphics/socials.svg b/src/graphics/socials.svg
new file mode 100644
index 0000000..e69de29
diff --git a/src/haml/archives.haml b/src/haml/archives.haml
new file mode 100644
index 0000000..e6d18b4
--- /dev/null
+++ b/src/haml/archives.haml
@@ -0,0 +1,38 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    Archives
+
+- block header
+    %h1.head-title
+        Archives
+
+- block content
+    .container
+        %dl
+        - for article in dates
+            %dt.h2
+                {{ article.locale_date }}
+            %dd.h4
+                %a{:href => "{{ SITEURL }}/{{ article.url }}"}
+                    {{ article.title }}
diff --git a/src/haml/article.haml b/src/haml/article.haml
new file mode 100644
index 0000000..1e64f64
--- /dev/null
+++ b/src/haml/article.haml
@@ -0,0 +1,79 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block metadescription
+    = article.description
+
+- block metakeywords
+    = article.keywords
+
+- block header
+    %h1.head-title<
+        = article.title
+
+- block contenthead
+
+- block content
+    .container
+        %section#content.body
+            %header
+
+                .h2<
+                    .article-socialshare<
+                        - include "includes/socialshare.html"
+                    = article.title
+
+                - import 'translations.html' as translations with context
+                = translations.translations_for(article)
+
+            .post-info
+                %h4
+                    %time.published{:datetime => "{{ article.date.isoformat() }}"}<
+                        = article.locale_date
+
+                - if article.modified
+                    %time.modified{:datetime => "{{ article.modified.isoformat() }}"}<
+                        = article.locale_modified
+
+                - if article.authors
+                    %address.vcard.author<
+                        by
+                        - for author in article.authors
+                            %a.url.fn{:href => "{{ SITEURL }}/{{ author.url }}"}<
+                                = author
+
+                - if article.tags
+                    %p<
+                        Tags:
+                            - for tag in article.tags
+                                %a{:href => "{{ SITEURL }}/{{ tag.url }}"}
+                                    = tag.name
+                                - if not loop.last
+                                    ,
+
+                - if article.license
+                    %p<
+                        Article license:
+                            = article.license
+
+            .entry-content<
+                = article.content
diff --git a/src/haml/author.haml b/src/haml/author.haml
new file mode 100644
index 0000000..333a15e
--- /dev/null
+++ b/src/haml/author.haml
@@ -0,0 +1,30 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/blog.html"
+
+- block title
+    Articles by
+    = author
+
+- block header
+    %h1.head-title
+        Articles by
+        = author
diff --git a/src/haml/authors.haml b/src/haml/authors.haml
new file mode 100644
index 0000000..75ed8ea
--- /dev/null
+++ b/src/haml/authors.haml
@@ -0,0 +1,39 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    Authors
+
+- block header
+    %h1.head-title
+        Authors
+
+
+- block content
+    .container
+        - for author, articles in authors|sort
+            .h2
+                %a{:href => "{{ SITEURL }}/{{ author.url }}"}
+                    = author
+                (
+                = articles|count
+                )
diff --git a/src/haml/base/base.haml b/src/haml/base/base.haml
new file mode 100644
index 0000000..c8a9a9a
--- /dev/null
+++ b/src/haml/base/base.haml
@@ -0,0 +1,110 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+!!!
+%html{:lang => "{{ LANGUAGE_CODE }}"}
+    %head
+        %meta{:charset => "utf-8"}
+        %meta{:http-equiv => "X-UA-Compatible", :content => "IE-edge"}
+        %meta{:name => "viewport", :content => "width=device-width, initial-scale=1, user-scalable=no"}
+        %meta{:name => "theme-color", :content => "#4a86cf"}
+        %meta{:name => "msapplication-navbutton-color", :content => "#4a86cf"}
+        %meta{:name => "apple-mobile-web-app-status-bar-style", :content => "#4a86cf"}
+
+        %title {% block title %}{{ SITENAME }}{% endblock %} - {{ SITEDOMAIN }}
+        %meta{:name => "description", :content => "{% block metadescription %}{% endblock %}"}
+        %meta{:name => "keywords", :content => "{% block metakeywords %}{% endblock %}"}
+
+        - block meta
+
+        %link{:rel => "dns-prefetch", :href => "//fonts.googleapis.com"}
+        %link{:rel => "alternate", :type => "application/rss+xml", :title => "{{ SITENAME }} feed", :href => 
"/rss"}
+        %link{:rel => "icon", :href => "{{ SITEURL }}/theme/img/icon-32x32.png"}
+        %link{:rel => "icon", :href => "{{ SITEURL }}/theme/img/icon-192x192.png"}
+        %link{:rel => "apple-touch-icon-precompose", :href => "{{ SITEURL }}/theme/img/icon-180x180.png"}
+        %link{:rel => "msapplication-TileImage", :href => "{{ SITEURL }}/theme/img/icon-270x270.png"}
+
+
+        %link{:rel => "stylesheet", :href => "{{ SITEURL }}/theme/css/screen.css"}
+        %noscript
+          %link{:rel => "stylesheet", :href => "{{ SITEURL }}/theme/css/noscript.css"}
+
+        /[if lt IE 9]
+            %script{:src => "https://oss.maxcdn.com/html5shiv/3.7.3/html5shiv.min.js"}
+            %script{:src => "https://oss.maxcdn.com/respond/1.4.2/respond.min.js"}
+
+        -# Feeds
+        - include "includes/feeds_head.html"
+
+    %body{:class => "{% block bodyclass %}default{% endblock %}"}
+        #header
+
+            .container
+                - include 'includes/navbar.html'
+
+                - block header
+
+
+        #content
+            #content-head
+                -block contenthead
+                    #breadcrumbs.container
+                        %a{:href => "{{ SITEURL }}", :title => "Home"}
+                            Home
+                        - block breadcrumbs
+
+            #content-body
+                - block content
+
+        #footer
+            .container
+                - block footer
+                    .row
+                        -# Foot links
+                        - include 'includes/footlinks.html'
+
+                        -# Socials
+                        - include 'includes/socials.html'
+
+                    .row
+                        .col.text-center.mt-5.mb-0
+                            All contents in this website are licensed under
+                            %a{:href => "https://creativecommons.org/share-your-work/public-domain/cc0/";, 
:title => "CC0", :target => "_blank"}
+                                Creative Commons CC0 License
+                            unless explicitly specified
+
+
+                    -#
+                        .row
+                            #copyright.col.text-center &copy;{{ SITEYEAR }}
+                                %a{:href => "{{ SITEURL }}", :title => "{{ SITENAME }}"}
+                                    {{ SITENAME }}
+                                |
+                                %a{:href => "{{ SITEURL }}/pages/legal.html"}
+                                    Legal terms and privacy policy
+
+        -# - include "includes/cookiesmessage.html"
+
+        #goup.btn-website
+            .oi.oi-caret-top
+
+        %script{:src => "{{ SITEURL }}/theme/js/scripts.js"}
+
+        - block extra_scripts
diff --git a/src/haml/base/blog.haml b/src/haml/base/blog.haml
new file mode 100644
index 0000000..7c6224e
--- /dev/null
+++ b/src/haml/base/blog.haml
@@ -0,0 +1,36 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block contenthead
+
+- block content
+    .container
+        %section#content
+
+            #content-title
+                - block content_title
+
+            #postlist
+                - for article in articles_page.object_list
+                    - include "includes/postlist_article.html"
+            - if articles_page.has_other_pages()
+                - include "includes/pagination.html"
diff --git a/src/haml/categories.haml b/src/haml/categories.haml
new file mode 100644
index 0000000..80ba82e
--- /dev/null
+++ b/src/haml/categories.haml
@@ -0,0 +1,43 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    Categories
+
+- block header
+    %h1.head-title
+        Categories
+
+- block contenthead
+
+- block content
+    .container
+        .h2
+            Categories
+
+        - for category, articles in categories
+            .h3
+                %a{:href => "{{ SITEURL }}/{{ category.url }}"}
+                    {{ category }}
+                (
+                = articles|count
+                )
diff --git a/src/haml/category.haml b/src/haml/category.haml
new file mode 100644
index 0000000..87fe910
--- /dev/null
+++ b/src/haml/category.haml
@@ -0,0 +1,28 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/blog.html"
+
+- block title
+    = category
+
+- block header
+    %h1.head-title
+        = category
diff --git a/src/haml/includes/cookiesmessage.haml b/src/haml/includes/cookiesmessage.haml
new file mode 100644
index 0000000..59c6060
--- /dev/null
+++ b/src/haml/includes/cookiesmessage.haml
@@ -0,0 +1,31 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+#cookiesmessage
+    This website uses session cookies for basic site working and third party cookies to enhance user 
experience through analytics.
+    If you continue browsing it, you accept our cookies policy and our privacy policy and legal terms.
+    You can learn more about at our
+    %a{:href => "{{ SITEURL }}/pages/legal.html"} Legal terms and privacy policy
+
+    .buttons
+        %button.btn.btn-default.decline
+            Decline
+        %button.btn.btn-website.accept
+            Accept
diff --git a/src/haml/includes/feeds_head.haml b/src/haml/includes/feeds_head.haml
new file mode 100644
index 0000000..d1b9d54
--- /dev/null
+++ b/src/haml/includes/feeds_head.haml
@@ -0,0 +1,43 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- if FEED_ALL_ATOM
+    %link{:href => "{{ FEED_DOMAIN }}/{{ FEED_ALL_ATOM }}", :type => "application/atom+xml", :rel => 
"alternate", :title => "{{ SITENAME }} Full Atom Feed"}
+
+- if FEED_ALL_RSS
+    %link{:href => "{{ FEED_DOMAIN }}/{{ FEED_ALL_RSS }}", :type => "application/rss+xml", :rel => 
"alternate", :title => "{{ SITENAME }} Full RSS Feed"}
+
+- if FEED_ATOM
+    %link{:href => "{{ FEED_DOMAIN }}/{{ FEED_ATOM }}", :type => "application/atom+xml", :rel => 
"alternate", :title => "{{ SITENAME }} Atom Feed"}
+
+- if FEED_RSS
+    %link{:href => "{{ FEED_DOMAIN }}/{{ FEED_RSS }}", :type => "application/rss+xml", :rel => "alternate", 
:title => "{{ SITENAME }} RSS Feed"}
+
+- if CATEGORY_FEED_ATOM and category
+    %link{:href => "{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_ATOM|format(category.slug) }}", :type => 
"application/atom+xml", :rel => "alternate", :title => "{{ SITENAME }} Categories Atom Feed"}
+
+- if CATEGORY_FEED_RSS and category
+    %link{:href => "{{ FEED_DOMAIN }}/{{ CATEGORY_FEED_RSS|format(category.slug) }}", :type => 
"application/rss+xml", :rel => "alternate", :title => "{{ SITENAME }} Categories RSS Feed"}
+
+- if TAG_FEED_ATOM and tag
+    %link{:href => "{{ FEED_DOMAIN }}/{{ TAG_FEED_ATOM|format(tag.slug) }}", :type => 
"application/atom+xml", :rel => "alternate", :title => "{{ SITENAME }} Tags Atom Feed"}
+
+- if TAG_FEED_RSS and tag
+    %link{:href => "{{ FEED_DOMAIN }}/{{ TAG_FEED_RSS|format(tag.slug) }}", :type => "application/rss+xml", 
:rel => "alternate", :title => "{{ SITENAME }} Tags RSS Feed"}
diff --git a/src/haml/includes/footlinks.haml b/src/haml/includes/footlinks.haml
new file mode 100644
index 0000000..69d1ed6
--- /dev/null
+++ b/src/haml/includes/footlinks.haml
@@ -0,0 +1,47 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+.footlinks.col-12.col-md-6
+    .row
+        .col-6
+            %ul
+                - for link in LINKS
+                    - if loop.first
+                        %li
+                            %strong
+                                %a{:href => "{{ link.1 }}"}
+                                    = link.0
+                    - else
+                        %li
+                            %a{:href => "{{ link.1 }}"}
+                                = link.0
+
+        .col-6
+            %ul
+                - for link in GUADEC_LINKS
+                    - if loop.first
+                        %li
+                            %strong
+                                %a{:href => "{{ link.1 }}"}
+                                    = link.0
+                    - else
+                        %li
+                            %a{:href => "{{ link.1 }}"}
+                                = link.0
diff --git a/src/haml/includes/navbar.haml b/src/haml/includes/navbar.haml
new file mode 100644
index 0000000..ef6d5d9
--- /dev/null
+++ b/src/haml/includes/navbar.haml
@@ -0,0 +1,44 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+%nav#menubar.navbar.fixed-top.navbar-dark.navbar-expand-lg
+    .container
+        %button.navbar-toggler{:type => "button", :data-toggle => "collapse", :data-target => 
"#navbarSupportedContent", :aria-controls => "navbarSupportedContent", :aria-expanded => "false", :aria-label 
=> "Toggle navigation"}
+            %span.navbar-toggler-icon
+
+        #navbarSupportedContent.collapse.navbar-collapse
+
+            %ul.navbar-nav
+                - for menu, content in MENU.items():
+                    - if content is mapping
+                        %li.nav-item.dropdown
+                            %a#navbarDropdown.nav-link.dropdown-toggle{:role => "button", :data-toggle => 
"dropdown", :aria-haspopup => "true", :aria-expanded => "false", :href => "#"}
+                                = menu
+                            .dropdown-menu{:aria-labelledby => "navbarDropdown"}
+                                - for submenu, subcontent in content.items()
+                                    - if subcontent:
+                                        %a.dropdown-item{:href => "{{ subcontent }}"}
+                                            = submenu
+                                    - else
+                                        .dropdown-divider
+                    - else
+                        %li.nav-item
+                            %a.nav-link{:href => "{{ content }}"}
+                                = menu
diff --git a/src/haml/includes/pagination.haml b/src/haml/includes/pagination.haml
new file mode 100644
index 0000000..081c5a4
--- /dev/null
+++ b/src/haml/includes/pagination.haml
@@ -0,0 +1,33 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- if articles_paginator.num_pages > 1
+    #pagination
+        %ul.pagination
+            %li
+                - if articles_page.has_previous()
+                    %a{:href => "{{ SITEURL }}/{{ articles_previous_page.url }}"}
+                        &laquo;
+            %li
+                Page {{ articles_page.number }} / {{ articles_paginator.num_pages }}
+            %li
+                - if articles_page.has_next()
+                    %a{:href => "{{ SITEURL }}/{{ articles_next_page.url }}"}
+                        &raquo;
diff --git a/src/haml/includes/postlist_article.haml b/src/haml/includes/postlist_article.haml
new file mode 100644
index 0000000..1dc43d7
--- /dev/null
+++ b/src/haml/includes/postlist_article.haml
@@ -0,0 +1,46 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+%article.hentry
+    %header
+        - if article.postimage
+            %img.post-image{:src => "{{ SITEURL }}/images/{{ article.postimage }}"}
+
+        %h2.entry-title
+            %a{:href => "{{ SITEURL }}/{{ article.url }}", :rel => "bookmark", :title => "Permalink to {{ 
article.title|striptags }}"}
+                = article.title
+
+    .post-info
+        %time.published{:datetime => "{{ article.date.isoformat() }}"}
+            = article.locale_date
+
+        %address.vcard.author
+            by
+            - for author in article.authors
+                %a.url.fn{:href => "{{ SITEURL }}/{{ author.url }}"}
+                    = author
+
+    .entry-content
+        = article.summary
+
+    %footer
+        %a.btn.btn-primary{:href => "{{ SITEURL }}/{{ article.url }}"}
+            Read more
+        - include "includes/socialshare.html"
diff --git a/src/haml/includes/socials.haml b/src/haml/includes/socials.haml
new file mode 100644
index 0000000..05b4096
--- /dev/null
+++ b/src/haml/includes/socials.haml
@@ -0,0 +1,24 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+.socials
+    - for social in SOCIAL
+        %a.social-round-s{:href => "{{ social.1 }}", :class => "social-{{ social.0.split()|join|lower 
}}-sw", :target => "_blank", :rel => "nofollow", :title => "{{ social.0 }}"}
+    %a.social-round-s.social-qrcode-sw.qrcode{:data-url => "{{ SITEURL }}", :href => "#", :rel => 
"nofollow", :title => "QR Code"}
diff --git a/src/haml/includes/socialshare.haml b/src/haml/includes/socialshare.haml
new file mode 100644
index 0000000..317fc14
--- /dev/null
+++ b/src/haml/includes/socialshare.haml
@@ -0,0 +1,25 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+#socialshare
+    %a.social-round-s.social-facebook-sw{:href => 
"http://www.facebook.com/sharer.php?u=https://matrixhas.me/{{ article.url }}", :target => "_blank", :rel => 
"nofollow", :title => "Share with Facebook"}
+    %a.social-round-s.social-twitter-sw{:href => 
"https://twitter.com/intent/tweet?url=https://matrixhas.me/{{ article.url }}&amp;text={{ '@matrixhas.me  - 
'|urlencode }}{{ article.title|truncate(80)|urlencode }} {{ article.hashtags|urlencode }}", :target => 
"_blank", :rel => "nofollow", :title => "Share with Twitter"}
+    %a.social-round-s.social-googleplus-sw{:href => 
"https://plus.google.com/share?url=https://matrixhas.me/{{ article.url|urlencode }}", :target => "_blank", 
:rel => "nofollow", :title => "Share with Google+"}
+    %a.social-round-s.social-qrcode-sw.qrcode{:data-url => "https://matrixhas.me/{{ article.url }}", :href 
=> "#", :target => "_blank", :rel => "nofollow", :title => "QR Code"}
diff --git a/src/haml/includes/translations.haml b/src/haml/includes/translations.haml
new file mode 100644
index 0000000..67d8ac0
--- /dev/null
+++ b/src/haml/includes/translations.haml
@@ -0,0 +1,26 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- macro translations_for(article)
+    - if article.translations
+        Translations:
+        - for translation in article.translations
+            %a{:href => "{{ SITEURL }}/{{ translation.url }}"}
+                {{ translation.lang }}
diff --git a/src/haml/index.haml b/src/haml/index.haml
new file mode 100644
index 0000000..24e8917
--- /dev/null
+++ b/src/haml/index.haml
@@ -0,0 +1,136 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+  {{ SITENAME }}
+
+- block metadescription
+  {{ SITENAME }} website
+
+- block metakeywords
+  {{ SITENAME }}, {{ SITEDOMAIN }}, website
+
+- block contenthead
+
+- block header
+
+    .container
+        .row.hero-home
+            .col
+                .h1
+                    The
+                    %img{:src => "/theme/img/gnome-logo.svg", :alt => "GNOME", :height => "60"}
+                    conference
+
+                .h1.guadec
+                    GUADEC
+
+                .h4
+                    {{ GUADEC_LOCATION }}
+
+                .h5.thin-text
+                    {{ GUADEC_DATES }}
+
+
+- block content
+    .container
+        .row.intro-home
+            .col
+                -# %a{:href => "https://www.flickr.com/photos/89175706@N00/28434184137/in/photostream/"}
+                -#     %img{:src => "/images/group_photo-28434184137_f3102ac89e_b.jpg", :alt => "CC BY-SA 
GuilleFuertes" }
+                .h4.text-center GUADEC brings together Free Software Enthusiasts and professionals from all 
over the world. Join us for six days of talks, demos, discussion, parties, games and more.
+
+        -if SPONSORS
+            .row.sponsors-home
+                .col
+                    .h2 Sponsors
+                    - for name, url, image in SPONSORS:
+                        %a{:href => "{{ url }}", :rel => "nofollow", :target => "_blank"}
+                            %img{:src => "/images/sponsors/{{ image }}", :alt => "{{ name }}", :height => 
"50"}
+
+        .row.subintro-home
+            .col
+                %p Join us to find out about the latest technical developments, learn new skills and tools, 
attend talks by leading experts, and participate in workshops and discussions. You will also get the 
opportunity to participate in the GNOME project, meet community members, as well as connect with local groups 
and organisations.
+
+    -#.highlights-home
+        .container
+            .row
+                .highlight.dates-home.col-md-4.text-center
+                    .icon.oi.oi-calendar
+                    .h5
+                        SAVE THE DATE
+                    %p
+                        Days 1-3 are
+                        %a{:href => "/pages/schedule.html"}
+                            talks,
+                        days 4-6 are
+                        %a{:href => "/pages/unconference.html"}
+                            workshops and training
+
+                .highlight.talks-home.col-md-4.text-center
+                    .icon.oi.oi-chat
+                    .h5
+                        TALKS
+                    %p
+                        See the talks schedule
+                        %a{:href => "/pages/schedule.html"}
+                            here
+
+                .highlight.register-home.col-md-4.text-center
+                    - if OPEN_REGISTRATION
+                        %a{:href => "https://registration.guadec.org/";, :rel => "nofollow", :target => 
"_blank"}
+                            .icon.oi.oi-circle-check
+                            .h5
+                                REGISTER
+                            %p
+                                Registration is open now!
+
+                    - else
+                        .icon.oi.oi-circle-check
+                        .h5
+                            REGISTER
+                        %p
+                            Registration is not open yet.
+
+
+    .container
+
+        - if articles_page.object_list
+            .row.news-home
+                .col
+                    .h2.text-center  News
+
+            .row.news-home-articles
+                - for article in articles_page.object_list[:3]
+                    -#- include "includes/postlist_article.html"
+                    .news-article.col-md-4
+                        %a.h5{:href => "{{ article.url }}", :title => "{{ article.title }}"}
+                            = article.title
+                        %p
+                            = article.summary
+                        %a.button{:href => "{{ article.url }}"}
+                            Read more
+
+        .row.social-home
+            .col.text-center
+                - include "includes/socials.html"
+                .h4 Follow us for news and updates
diff --git a/src/haml/page.haml b/src/haml/page.haml
new file mode 100644
index 0000000..f2727cf
--- /dev/null
+++ b/src/haml/page.haml
@@ -0,0 +1,41 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    = page.title
+
+- block header
+    %h1.head-title<
+        = page.title
+
+- block contenthead
+
+- block content
+    .container
+        .row
+            .col
+                - import 'includes/translations.html' as translations with context
+                = translations.translations_for(page)
+                = page.content
+                - if page.modified
+                    %p
+                        Last updated: {{ page.locale_modified }}
diff --git a/src/haml/period_archives.haml b/src/haml/period_archives.haml
new file mode 100644
index 0000000..04658fb
--- /dev/null
+++ b/src/haml/period_archives.haml
@@ -0,0 +1,46 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    Archives for
+    = period | reverse | join(' ')
+
+- block header
+    %h1.head-title
+        Archives for
+        = period | reverse | join(' ')
+
+- block contenthead
+
+- block content
+    .container
+        .h2
+            Archives for
+            = period | reverse | join(' ')
+
+        %dl
+            - for article in dates
+                %dt
+                    = article.locale_date
+                %dd
+                    %a{:href => "{{ SITEURL }}/{{ article.url }}"}
+                        = article.title
diff --git a/src/haml/tag.haml b/src/haml/tag.haml
new file mode 100644
index 0000000..e499133
--- /dev/null
+++ b/src/haml/tag.haml
@@ -0,0 +1,32 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/blog.html"
+
+- block title
+    Articles tagged as
+    = tag
+
+- block header
+    %h1.head-title
+        Articles tagged as
+        = tag
+
+- block contenthead
diff --git a/src/haml/tags.haml b/src/haml/tags.haml
new file mode 100644
index 0000000..835fe28
--- /dev/null
+++ b/src/haml/tags.haml
@@ -0,0 +1,44 @@
+-# Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+-#
+-# Permission is hereby granted, free of charge, to any person obtaining a copy of
+-# this software and associated documentation files (the "Software"), to deal in
+-# the Software without restriction, including without limitation the rights to
+-# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+-# of the Software, and to permit persons to whom the Software is furnished to do
+-# so, subject to the following conditions:
+-#
+-# The above copyright notice and this permission notice shall be included in all
+-# copies or substantial portions of the Software.
+-#
+-# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+-# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+-# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+-# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+-# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+-# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+-# SOFTWARE.
+
+- extends "base/base.html"
+
+- block title
+    Tags
+
+- block header
+    %h1.head-title
+        Tags
+
+- block contenthead
+
+- block content
+    .container
+        - if tags
+            %ul
+                - for tag, articles in tags|sort
+                    %li
+                        %a{:href => "{{ SITEURL }}/{{ tag.url }}"}
+                            {{ tag }}
+                        (
+                            = articles|count
+                        )
+        - else
+            %p There are no tags to list
diff --git a/src/img/Gnomelogo-footprint.png b/src/img/Gnomelogo-footprint.png
new file mode 100644
index 0000000..ba1d420
Binary files /dev/null and b/src/img/Gnomelogo-footprint.png differ
diff --git a/src/img/Gnomelogo-footprint.svg b/src/img/Gnomelogo-footprint.svg
new file mode 100644
index 0000000..c1febf4
--- /dev/null
+++ b/src/img/Gnomelogo-footprint.svg
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="600"
+   height="600"
+   viewBox="0 0 95.991 150.915"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="Gnomelogo-footprint.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="1153"
+     inkscape:window-width="1916"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="0.67833333"
+     inkscape:cx="300"
+     inkscape:cy="299.2629"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0" /><defs
+     id="defs1391" /><g
+     style="fill-rule:nonzero;stroke:none;stroke-miterlimit:4;fill:#4a86cf;fill-opacity:1"
+     id="g1365"
+     transform="matrix(1.213211,0,0,1.213211,-10.36596,3.720334)"><g
+       id="g1367"
+       style="fill:#4a86cf;fill-opacity:1"><path
+         d="M 86.068,0 C 61.466,0 56.851,35.041 70.691,35.041 C 84.529,35.041 110.671,0 86.068,0 z "
+         id="path1369"
+         style="fill:#4a86cf;fill-opacity:1" /><path
+         d="M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 C 32.976,6.171 37.845,30.249 
45.217,30.699 z "
+         id="path1371"
+         style="fill:#4a86cf;fill-opacity:1" /><path
+         d="M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 C -5.7,35.89 6.204,50.759 
11.445,48.453 z "
+         id="path1373"
+         style="fill:#4a86cf;fill-opacity:1" /><path
+         d="M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 C 10.539,18.961 19.978,37.916 
26.212,36.642 L 26.212,36.642 z "
+         id="path1375"
+         style="fill:#4a86cf;fill-opacity:1" /><path
+         d="M 58.791,93.913 C 59.898,102.367 52.589,106.542 45.431,101.092 C 22.644,83.743 83.16,75.088 
79.171,51.386 C 75.86,31.712 15.495,37.769 8.621,68.553 C 3.968,89.374 27.774,118.26 52.614,118.26 C 
64.834,118.26 78.929,107.226 81.566,93.248 C 83.58,82.589 57.867,86.86 58.791,93.913 L 58.791,93.913 z "
+         id="newshape"
+         style="fill:#4a86cf;fill-opacity:1" /></g></g></svg>
\ No newline at end of file
diff --git a/src/img/black_pixel.png b/src/img/black_pixel.png
new file mode 100644
index 0000000..ad7744e
Binary files /dev/null and b/src/img/black_pixel.png differ
diff --git a/src/img/gnome-logo.svg b/src/img/gnome-logo.svg
new file mode 100644
index 0000000..34c4308
--- /dev/null
+++ b/src/img/gnome-logo.svg
@@ -0,0 +1,155 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   width="151.16637"
+   height="64.129845"
+   viewBox="0 0 39.996099 16.967689"
+   version="1.1"
+   id="svg294"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="gnome-logo.svg">
+  <defs
+     id="defs288" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.8"
+     inkscape:cx="87.300271"
+     inkscape:cy="-143.01536"
+     inkscape:document-units="mm"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:pagecheckerboard="true"
+     fit-margin-top="10"
+     fit-margin-left="10"
+     fit-margin-right="10"
+     fit-margin-bottom="10"
+     units="px"
+     inkscape:window-width="3840"
+     inkscape:window-height="2089"
+     inkscape:window-x="0"
+     inkscape:window-y="34"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata291">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-60.510876,-28.846515)">
+    <g
+       
style="opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:1.7902559;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       id="g4659"
+       transform="matrix(0.2644086,0,0,0.2644086,-161.0636,-54.355669)">
+      <g
+         
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:15.11990929;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+         id="g4657"
+         transform="matrix(0.11840388,0,0,0.11840388,865.19335,299.21794)">
+        <g
+           
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+           id="g4655"
+           transform="matrix(1.293235,0,0,1.293235,-4878.321,-1224.915)">
+          <g
+             id="g4635"
+             
style="vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             transform="matrix(2.438586,0,0,2.438586,3659.952,1113.451)">
+            <g
+               id="g4633"
+               
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">
+              <path
+                 id="path4623"
+                 
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="M 86.068,0 C 61.466,0 56.851,35.041 70.691,35.041 84.529,35.041 110.671,0 86.068,0 Z"
+                 inkscape:connector-curvature="0" />
+              <path
+                 id="path4625"
+                 
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 32.976,6.171 37.845,30.249 
45.217,30.699 Z"
+                 inkscape:connector-curvature="0" />
+              <path
+                 id="path4627"
+                 
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 -5.7,35.89 6.204,50.759 
11.445,48.453 Z"
+                 inkscape:connector-curvature="0" />
+              <path
+                 id="path4629"
+                 
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 10.539,18.961 19.978,37.916 
26.212,36.642 Z"
+                 inkscape:connector-curvature="0" />
+              <path
+                 id="path4631"
+                 
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:4.79439306;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="m 58.791,93.913 c 1.107,8.454 -6.202,12.629 -13.36,7.179 C 22.644,83.743 83.16,75.088 
79.171,51.386 75.86,31.712 15.495,37.769 8.621,68.553 3.968,89.374 27.774,118.26 52.614,118.26 c 12.22,0 
26.315,-11.034 28.952,-25.012 C 83.58,82.589 57.867,86.86 58.791,93.913 Z"
+                 inkscape:connector-curvature="0" />
+            </g>
+          </g>
+          <g
+             
style="vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+             id="g4653">
+            <path
+               id="path4637"
+               
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:148.699646px;line-height:125%;font-family:'Bitstream
 Vera 
Sans';text-align:start;writing-mode:lr-tb;text-anchor:start;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               d="m 4176.2963,1214.4401 c -15.1078,0.4069 -27.0386,5.8367 -35.8126,16.25 -9.0861,10.8369 
-13.6562,25.8104 -13.6562,44.9063 0,19.0432 4.5703,33.9757 13.6562,44.8124 9.1305,10.8369 21.6664,16.25 
37.6563,16.25 16.034,0 28.6014,-5.4131 37.6875,-16.25 9.0859,-10.8367 13.6251,-25.7692 13.625,-44.8124 
-1e-4,-19.0959 -4.5391,-34.0694 -13.625,-44.9063 -9.0861,-10.8366 -21.6536,-16.2499 -37.6875,-16.25 -0.6246,0 
-1.2296,-0.016 -1.8437,0 z m 1.125,22 c 0.2415,-0.01 0.4737,0 0.7187,0 7.8833,10e-5 13.9919,3.4114 
18.3125,10.25 4.3203,6.8388 6.4999,16.4913 6.5,28.9063 0,12.3623 -2.1799,21.9427 -6.5,28.7812 -4.3204,6.8389 
-10.4293,10.2812 -18.3125,10.2812 -7.8391,0 -13.8983,-3.4423 -18.2187,-10.2812 -4.3204,-6.8385 
-6.4999,-16.4189 -6.5,-28.7812 0,-12.4149 2.1798,-22.0675 6.5,-28.9063 4.1852,-6.6249 10.0123,-10.0428 
17.5,-10.25 z"
+               inkscape:connector-curvature="0" />
+            <path
+               id="path4639"
+               
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:148.699646px;line-height:125%;font-family:'Bitstream
 Vera 
Sans';text-align:start;writing-mode:lr-tb;text-anchor:start;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               d="m 4005.6293,1325.612 c -13.3076,11.1757 -33.1067,11.0472 -41.3549,11.0472 -16.6133,0 
-29.7747,-5.471 -39.4842,-16.413 -9.7097,-10.9946 -14.5644,-25.8819 -14.5644,-44.6622 0,-18.9906 
4.9438,-33.9305 14.8316,-44.82 9.8878,-10.8892 23.4277,-16.3339 40.62,-16.334 6.6363,10e-5 12.9831,0.7366 
19.0406,2.2094 6.1019,1.473 11.8475,3.6562 17.2368,6.5494 l -6.921,20.4608 c -3.0298,-1.6586 -6.4987,-3.2932 
-9.7145,-4.4424 -5.4784,-1.8411 -10.979,-2.7617 -16.5018,-2.7618 -10.2442,10e-5 -18.15,3.3932 
-23.7173,10.1792 -5.523,6.7336 -8.2844,16.3867 -8.2844,28.9594 0,12.4676 2.6723,22.0945 8.0172,28.8806 
5.3446,6.7861 13.3768,10.1791 22.7818,10.1791 9.5548,0 15.4728,-2.4084 18.6291,-4.9461 v -20.3835 h -20.7001 
v -20.3584 h 40.0855"
+               inkscape:connector-curvature="0" />
+            <path
+               id="path4641"
+               
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:148.699646px;line-height:125%;font-family:'Bitstream
 Vera 
Sans';text-align:start;writing-mode:lr-tb;text-anchor:start;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               d="m 4023.2108,1216.5605 h 16.2279 l 51.2775,70.8022 v -70.8022 h 21.8853 v 117.8103 h 
-16.2279 l -51.2774,-70.8022 v 70.8022 h -21.8854 v -117.8103"
+               inkscape:connector-curvature="0" />
+            <path
+               id="path4643"
+               
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:148.699646px;line-height:125%;font-family:'Bitstream
 Vera 
Sans';text-align:start;writing-mode:lr-tb;text-anchor:start;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               d="m 4246.3361,1216.5605 h 32.7366 l 22.7151,73.5479 22.8487,-73.5479 h 27.6698 l 
12.5,117.8103 h -24.3186 l -7.5,-73.668 -22.9823,74.0213 h -16.3015 l -22.9824,-76.5213 -7.5,76.168 h 
-24.3854 l 12.5,-117.8103"
+               inkscape:connector-curvature="0" />
+            <path
+               id="path4645"
+               
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:148.699646px;line-height:125%;font-family:'Bitstream
 Vera 
Sans';text-align:start;writing-mode:lr-tb;text-anchor:start;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+               d="m 4382.3597,1216.5605 h 69.4147 v 22.9624 h -43.6933 v 24.4365 h 33.5877 v 20.4623 h 
-33.5877 v 26.9868 h 45.1631 v 22.9623 h -70.8845 v -117.8103"
+               inkscape:connector-curvature="0" />
+            <g
+               id="g4651"
+               style="font-style:normal;font-weight:normal;font-size:30.68958855px;font-family:'Bitstream 
Vera 
Sans';vector-effect:none;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1">
+              <path
+                 inkscape:connector-curvature="0"
+                 id="path4647"
+                 
style="letter-spacing:0.2523815;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="m 4474.5283,1193.3702 h 18.9262 v 2.5475 h -7.9421 v 19.8253 h -3.042 v -19.8253 h 
-7.9421 v -2.5475" />
+              <path
+                 inkscape:connector-curvature="0"
+                 id="path4649"
+                 
style="letter-spacing:0.2523815;vector-effect:none;fill:#ffffff;fill-opacity:1;stroke-width:11.69154072;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+                 d="m 4496.644,1193.3702 h 4.5105 l 5.7093,15.2249 5.7394,-15.2249 h 4.5105 v 22.3728 h 
-2.9521 v -19.6455 l -5.7693,15.3448 h -3.042 l -5.7692,-15.3448 v 19.6455 h -2.9371 v -22.3728" />
+            </g>
+          </g>
+        </g>
+      </g>
+    </g>
+  </g>
+</svg>
diff --git a/src/img/icon-180x180.png b/src/img/icon-180x180.png
new file mode 100644
index 0000000..56b6a6d
Binary files /dev/null and b/src/img/icon-180x180.png differ
diff --git a/src/img/icon-192x192.png b/src/img/icon-192x192.png
new file mode 100644
index 0000000..c29fd5b
Binary files /dev/null and b/src/img/icon-192x192.png differ
diff --git a/src/img/icon-270x270.png b/src/img/icon-270x270.png
new file mode 100644
index 0000000..6620789
Binary files /dev/null and b/src/img/icon-270x270.png differ
diff --git a/src/img/icon-32x32.png b/src/img/icon-32x32.png
new file mode 100644
index 0000000..342b838
Binary files /dev/null and b/src/img/icon-32x32.png differ
diff --git a/src/img/skyline.png b/src/img/skyline.png
new file mode 100644
index 0000000..8e86ca5
Binary files /dev/null and b/src/img/skyline.png differ
diff --git a/src/img/social/facebook-sw.png b/src/img/social/facebook-sw.png
new file mode 100644
index 0000000..3450c6d
Binary files /dev/null and b/src/img/social/facebook-sw.png differ
diff --git a/src/img/social/googleplus-sw.png b/src/img/social/googleplus-sw.png
new file mode 100644
index 0000000..98a1264
Binary files /dev/null and b/src/img/social/googleplus-sw.png differ
diff --git a/src/img/social/instagram-lw.png b/src/img/social/instagram-lw.png
new file mode 100644
index 0000000..56c8b9e
Binary files /dev/null and b/src/img/social/instagram-lw.png differ
diff --git a/src/img/social/instagram-mw.png b/src/img/social/instagram-mw.png
new file mode 100644
index 0000000..366ae8b
Binary files /dev/null and b/src/img/social/instagram-mw.png differ
diff --git a/src/img/social/instagram-sw.png b/src/img/social/instagram-sw.png
new file mode 100644
index 0000000..8d2d233
Binary files /dev/null and b/src/img/social/instagram-sw.png differ
diff --git a/src/img/social/instagram-xlw.png b/src/img/social/instagram-xlw.png
new file mode 100644
index 0000000..919077d
Binary files /dev/null and b/src/img/social/instagram-xlw.png differ
diff --git a/src/img/social/mail-lw.png b/src/img/social/mail-lw.png
new file mode 100644
index 0000000..7fc9862
Binary files /dev/null and b/src/img/social/mail-lw.png differ
diff --git a/src/img/social/mail-mw.png b/src/img/social/mail-mw.png
new file mode 100644
index 0000000..f3c3a27
Binary files /dev/null and b/src/img/social/mail-mw.png differ
diff --git a/src/img/social/mail-sw.png b/src/img/social/mail-sw.png
new file mode 100644
index 0000000..9d5ec35
Binary files /dev/null and b/src/img/social/mail-sw.png differ
diff --git a/src/img/social/mail-xlw.png b/src/img/social/mail-xlw.png
new file mode 100644
index 0000000..f24088f
Binary files /dev/null and b/src/img/social/mail-xlw.png differ
diff --git a/src/img/social/pinterest-lw.png b/src/img/social/pinterest-lw.png
new file mode 100644
index 0000000..501308b
Binary files /dev/null and b/src/img/social/pinterest-lw.png differ
diff --git a/src/img/social/pinterest-mw.png b/src/img/social/pinterest-mw.png
new file mode 100644
index 0000000..4848fc6
Binary files /dev/null and b/src/img/social/pinterest-mw.png differ
diff --git a/src/img/social/pinterest-sw.png b/src/img/social/pinterest-sw.png
new file mode 100644
index 0000000..8e563d8
Binary files /dev/null and b/src/img/social/pinterest-sw.png differ
diff --git a/src/img/social/pinterest-xlw.png b/src/img/social/pinterest-xlw.png
new file mode 100644
index 0000000..4b2984e
Binary files /dev/null and b/src/img/social/pinterest-xlw.png differ
diff --git a/src/img/social/qrcode-sw.png b/src/img/social/qrcode-sw.png
new file mode 100644
index 0000000..9b887bd
Binary files /dev/null and b/src/img/social/qrcode-sw.png differ
diff --git a/src/img/social/rss-sw.png b/src/img/social/rss-sw.png
new file mode 100644
index 0000000..096d8bf
Binary files /dev/null and b/src/img/social/rss-sw.png differ
diff --git a/src/img/social/telegram-lw.png b/src/img/social/telegram-lw.png
new file mode 100644
index 0000000..6818fa7
Binary files /dev/null and b/src/img/social/telegram-lw.png differ
diff --git a/src/img/social/telegram-mw.png b/src/img/social/telegram-mw.png
new file mode 100644
index 0000000..7f2f2d5
Binary files /dev/null and b/src/img/social/telegram-mw.png differ
diff --git a/src/img/social/telegram-sw.png b/src/img/social/telegram-sw.png
new file mode 100644
index 0000000..b03a5b2
Binary files /dev/null and b/src/img/social/telegram-sw.png differ
diff --git a/src/img/social/telegram-xlw.png b/src/img/social/telegram-xlw.png
new file mode 100644
index 0000000..bc0be8e
Binary files /dev/null and b/src/img/social/telegram-xlw.png differ
diff --git a/src/img/social/twitter-sw.png b/src/img/social/twitter-sw.png
new file mode 100644
index 0000000..32f01ef
Binary files /dev/null and b/src/img/social/twitter-sw.png differ
diff --git a/src/img/social/whatsapp-lw.png b/src/img/social/whatsapp-lw.png
new file mode 100644
index 0000000..ebea66c
Binary files /dev/null and b/src/img/social/whatsapp-lw.png differ
diff --git a/src/img/social/whatsapp-mw.png b/src/img/social/whatsapp-mw.png
new file mode 100644
index 0000000..983e11e
Binary files /dev/null and b/src/img/social/whatsapp-mw.png differ
diff --git a/src/img/social/whatsapp-sw.png b/src/img/social/whatsapp-sw.png
new file mode 100644
index 0000000..815b87e
Binary files /dev/null and b/src/img/social/whatsapp-sw.png differ
diff --git a/src/img/social/whatsapp-xlw.png b/src/img/social/whatsapp-xlw.png
new file mode 100644
index 0000000..47f89d7
Binary files /dev/null and b/src/img/social/whatsapp-xlw.png differ
diff --git a/src/img/social/youtube-lw.png b/src/img/social/youtube-lw.png
new file mode 100644
index 0000000..f6aa637
Binary files /dev/null and b/src/img/social/youtube-lw.png differ
diff --git a/src/img/social/youtube-mw.png b/src/img/social/youtube-mw.png
new file mode 100644
index 0000000..44c4ea6
Binary files /dev/null and b/src/img/social/youtube-mw.png differ
diff --git a/src/img/social/youtube-sw.png b/src/img/social/youtube-sw.png
new file mode 100644
index 0000000..454a4c1
Binary files /dev/null and b/src/img/social/youtube-sw.png differ
diff --git a/src/img/social/youtube-xlw.png b/src/img/social/youtube-xlw.png
new file mode 100644
index 0000000..692cbdc
Binary files /dev/null and b/src/img/social/youtube-xlw.png differ
diff --git a/src/img/transparent_pixel.png b/src/img/transparent_pixel.png
new file mode 100644
index 0000000..e6f9e7e
Binary files /dev/null and b/src/img/transparent_pixel.png differ
diff --git a/src/img/website/empty.png b/src/img/website/empty.png
new file mode 100644
index 0000000..e6f9e7e
Binary files /dev/null and b/src/img/website/empty.png differ
diff --git a/src/img/white_pixel.png b/src/img/white_pixel.png
new file mode 100644
index 0000000..b4c1b0a
Binary files /dev/null and b/src/img/white_pixel.png differ
diff --git a/src/js/01-jquery-3.2.1.js b/src/js/01-jquery-3.2.1.js
new file mode 100644
index 0000000..d2d8ca4
--- /dev/null
+++ b/src/js/01-jquery-3.2.1.js
@@ -0,0 +1,10253 @@
+/*!
+ * jQuery JavaScript Library v3.2.1
+ * https://jquery.com/
+ *
+ * Includes Sizzle.js
+ * https://sizzlejs.com/
+ *
+ * Copyright JS Foundation and other contributors
+ * Released under the MIT license
+ * https://jquery.org/license
+ *
+ * Date: 2017-03-20T18:59Z
+ */
+( function( global, factory ) {
+
+       "use strict";
+
+       if ( typeof module === "object" && typeof module.exports === "object" ) {
+
+               // For CommonJS and CommonJS-like environments where a proper `window`
+               // is present, execute the factory and get jQuery.
+               // For environments that do not have a `window` with a `document`
+               // (such as Node.js), expose a factory as module.exports.
+               // This accentuates the need for the creation of a real `window`.
+               // e.g. var jQuery = require("jquery")(window);
+               // See ticket #14549 for more info.
+               module.exports = global.document ?
+                       factory( global, true ) :
+                       function( w ) {
+                               if ( !w.document ) {
+                                       throw new Error( "jQuery requires a window with a document" );
+                               }
+                               return factory( w );
+                       };
+       } else {
+               factory( global );
+       }
+
+// Pass this if window is not defined yet
+} )( typeof window !== "undefined" ? window : this, function( window, noGlobal ) {
+
+// Edge <= 12 - 13+, Firefox <=18 - 45+, IE 10 - 11, Safari 5.1 - 9+, iOS 6 - 9.1
+// throw exceptions when non-strict code (e.g., ASP.NET 4.5) accesses strict mode
+// arguments.callee.caller (trac-13335). But as of jQuery 3.0 (2016), strict mode should be common
+// enough that all such attempts are guarded in a try block.
+"use strict";
+
+var arr = [];
+
+var document = window.document;
+
+var getProto = Object.getPrototypeOf;
+
+var slice = arr.slice;
+
+var concat = arr.concat;
+
+var push = arr.push;
+
+var indexOf = arr.indexOf;
+
+var class2type = {};
+
+var toString = class2type.toString;
+
+var hasOwn = class2type.hasOwnProperty;
+
+var fnToString = hasOwn.toString;
+
+var ObjectFunctionString = fnToString.call( Object );
+
+var support = {};
+
+
+
+       function DOMEval( code, doc ) {
+               doc = doc || document;
+
+               var script = doc.createElement( "script" );
+
+               script.text = code;
+               doc.head.appendChild( script ).parentNode.removeChild( script );
+       }
+/* global Symbol */
+// Defining this global in .eslintrc.json would create a danger of using the global
+// unguarded in another place, it seems safer to define global only for this module
+
+
+
+var
+       version = "3.2.1",
+
+       // Define a local copy of jQuery
+       jQuery = function( selector, context ) {
+
+               // The jQuery object is actually just the init constructor 'enhanced'
+               // Need init if jQuery is called (just allow error to be thrown if not included)
+               return new jQuery.fn.init( selector, context );
+       },
+
+       // Support: Android <=4.0 only
+       // Make sure we trim BOM and NBSP
+       rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,
+
+       // Matches dashed string for camelizing
+       rmsPrefix = /^-ms-/,
+       rdashAlpha = /-([a-z])/g,
+
+       // Used by jQuery.camelCase as callback to replace()
+       fcamelCase = function( all, letter ) {
+               return letter.toUpperCase();
+       };
+
+jQuery.fn = jQuery.prototype = {
+
+       // The current version of jQuery being used
+       jquery: version,
+
+       constructor: jQuery,
+
+       // The default length of a jQuery object is 0
+       length: 0,
+
+       toArray: function() {
+               return slice.call( this );
+       },
+
+       // Get the Nth element in the matched element set OR
+       // Get the whole matched element set as a clean array
+       get: function( num ) {
+
+               // Return all the elements in a clean array
+               if ( num == null ) {
+                       return slice.call( this );
+               }
+
+               // Return just the one element from the set
+               return num < 0 ? this[ num + this.length ] : this[ num ];
+       },
+
+       // Take an array of elements and push it onto the stack
+       // (returning the new matched element set)
+       pushStack: function( elems ) {
+
+               // Build a new jQuery matched element set
+               var ret = jQuery.merge( this.constructor(), elems );
+
+               // Add the old object onto the stack (as a reference)
+               ret.prevObject = this;
+
+               // Return the newly-formed element set
+               return ret;
+       },
+
+       // Execute a callback for every element in the matched set.
+       each: function( callback ) {
+               return jQuery.each( this, callback );
+       },
+
+       map: function( callback ) {
+               return this.pushStack( jQuery.map( this, function( elem, i ) {
+                       return callback.call( elem, i, elem );
+               } ) );
+       },
+
+       slice: function() {
+               return this.pushStack( slice.apply( this, arguments ) );
+       },
+
+       first: function() {
+               return this.eq( 0 );
+       },
+
+       last: function() {
+               return this.eq( -1 );
+       },
+
+       eq: function( i ) {
+               var len = this.length,
+                       j = +i + ( i < 0 ? len : 0 );
+               return this.pushStack( j >= 0 && j < len ? [ this[ j ] ] : [] );
+       },
+
+       end: function() {
+               return this.prevObject || this.constructor();
+       },
+
+       // For internal use only.
+       // Behaves like an Array's method, not like a jQuery method.
+       push: push,
+       sort: arr.sort,
+       splice: arr.splice
+};
+
+jQuery.extend = jQuery.fn.extend = function() {
+       var options, name, src, copy, copyIsArray, clone,
+               target = arguments[ 0 ] || {},
+               i = 1,
+               length = arguments.length,
+               deep = false;
+
+       // Handle a deep copy situation
+       if ( typeof target === "boolean" ) {
+               deep = target;
+
+               // Skip the boolean and the target
+               target = arguments[ i ] || {};
+               i++;
+       }
+
+       // Handle case when target is a string or something (possible in deep copy)
+       if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
+               target = {};
+       }
+
+       // Extend jQuery itself if only one argument is passed
+       if ( i === length ) {
+               target = this;
+               i--;
+       }
+
+       for ( ; i < length; i++ ) {
+
+               // Only deal with non-null/undefined values
+               if ( ( options = arguments[ i ] ) != null ) {
+
+                       // Extend the base object
+                       for ( name in options ) {
+                               src = target[ name ];
+                               copy = options[ name ];
+
+                               // Prevent never-ending loop
+                               if ( target === copy ) {
+                                       continue;
+                               }
+
+                               // Recurse if we're merging plain objects or arrays
+                               if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
+                                       ( copyIsArray = Array.isArray( copy ) ) ) ) {
+
+                                       if ( copyIsArray ) {
+                                               copyIsArray = false;
+                                               clone = src && Array.isArray( src ) ? src : [];
+
+                                       } else {
+                                               clone = src && jQuery.isPlainObject( src ) ? src : {};
+                                       }
+
+                                       // Never move original objects, clone them
+                                       target[ name ] = jQuery.extend( deep, clone, copy );
+
+                               // Don't bring in undefined values
+                               } else if ( copy !== undefined ) {
+                                       target[ name ] = copy;
+                               }
+                       }
+               }
+       }
+
+       // Return the modified object
+       return target;
+};
+
+jQuery.extend( {
+
+       // Unique for each copy of jQuery on the page
+       expando: "jQuery" + ( version + Math.random() ).replace( /\D/g, "" ),
+
+       // Assume jQuery is ready without the ready module
+       isReady: true,
+
+       error: function( msg ) {
+               throw new Error( msg );
+       },
+
+       noop: function() {},
+
+       isFunction: function( obj ) {
+               return jQuery.type( obj ) === "function";
+       },
+
+       isWindow: function( obj ) {
+               return obj != null && obj === obj.window;
+       },
+
+       isNumeric: function( obj ) {
+
+               // As of jQuery 3.0, isNumeric is limited to
+               // strings and numbers (primitives or objects)
+               // that can be coerced to finite numbers (gh-2662)
+               var type = jQuery.type( obj );
+               return ( type === "number" || type === "string" ) &&
+
+                       // parseFloat NaNs numeric-cast false positives ("")
+                       // ...but misinterprets leading-number strings, particularly hex literals ("0x...")
+                       // subtraction forces infinities to NaN
+                       !isNaN( obj - parseFloat( obj ) );
+       },
+
+       isPlainObject: function( obj ) {
+               var proto, Ctor;
+
+               // Detect obvious negatives
+               // Use toString instead of jQuery.type to catch host objects
+               if ( !obj || toString.call( obj ) !== "[object Object]" ) {
+                       return false;
+               }
+
+               proto = getProto( obj );
+
+               // Objects with no prototype (e.g., `Object.create( null )`) are plain
+               if ( !proto ) {
+                       return true;
+               }
+
+               // Objects with prototype are plain iff they were constructed by a global Object function
+               Ctor = hasOwn.call( proto, "constructor" ) && proto.constructor;
+               return typeof Ctor === "function" && fnToString.call( Ctor ) === ObjectFunctionString;
+       },
+
+       isEmptyObject: function( obj ) {
+
+               /* eslint-disable no-unused-vars */
+               // See https://github.com/eslint/eslint/issues/6125
+               var name;
+
+               for ( name in obj ) {
+                       return false;
+               }
+               return true;
+       },
+
+       type: function( obj ) {
+               if ( obj == null ) {
+                       return obj + "";
+               }
+
+               // Support: Android <=2.3 only (functionish RegExp)
+               return typeof obj === "object" || typeof obj === "function" ?
+                       class2type[ toString.call( obj ) ] || "object" :
+                       typeof obj;
+       },
+
+       // Evaluates a script in a global context
+       globalEval: function( code ) {
+               DOMEval( code );
+       },
+
+       // Convert dashed to camelCase; used by the css and data modules
+       // Support: IE <=9 - 11, Edge 12 - 13
+       // Microsoft forgot to hump their vendor prefix (#9572)
+       camelCase: function( string ) {
+               return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
+       },
+
+       each: function( obj, callback ) {
+               var length, i = 0;
+
+               if ( isArrayLike( obj ) ) {
+                       length = obj.length;
+                       for ( ; i < length; i++ ) {
+                               if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+                                       break;
+                               }
+                       }
+               } else {
+                       for ( i in obj ) {
+                               if ( callback.call( obj[ i ], i, obj[ i ] ) === false ) {
+                                       break;
+                               }
+                       }
+               }
+
+               return obj;
+       },
+
+       // Support: Android <=4.0 only
+       trim: function( text ) {
+               return text == null ?
+                       "" :
+                       ( text + "" ).replace( rtrim, "" );
+       },
+
+       // results is for internal usage only
+       makeArray: function( arr, results ) {
+               var ret = results || [];
+
+               if ( arr != null ) {
+                       if ( isArrayLike( Object( arr ) ) ) {
+                               jQuery.merge( ret,
+                                       typeof arr === "string" ?
+                                       [ arr ] : arr
+                               );
+                       } else {
+                               push.call( ret, arr );
+                       }
+               }
+
+               return ret;
+       },
+
+       inArray: function( elem, arr, i ) {
+               return arr == null ? -1 : indexOf.call( arr, elem, i );
+       },
+
+       // Support: Android <=4.0 only, PhantomJS 1 only
+       // push.apply(_, arraylike) throws on ancient WebKit
+       merge: function( first, second ) {
+               var len = +second.length,
+                       j = 0,
+                       i = first.length;
+
+               for ( ; j < len; j++ ) {
+                       first[ i++ ] = second[ j ];
+               }
+
+               first.length = i;
+
+               return first;
+       },
+
+       grep: function( elems, callback, invert ) {
+               var callbackInverse,
+                       matches = [],
+                       i = 0,
+                       length = elems.length,
+                       callbackExpect = !invert;
+
+               // Go through the array, only saving the items
+               // that pass the validator function
+               for ( ; i < length; i++ ) {
+                       callbackInverse = !callback( elems[ i ], i );
+                       if ( callbackInverse !== callbackExpect ) {
+                               matches.push( elems[ i ] );
+                       }
+               }
+
+               return matches;
+       },
+
+       // arg is for internal usage only
+       map: function( elems, callback, arg ) {
+               var length, value,
+                       i = 0,
+                       ret = [];
+
+               // Go through the array, translating each of the items to their new values
+               if ( isArrayLike( elems ) ) {
+                       length = elems.length;
+                       for ( ; i < length; i++ ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret.push( value );
+                               }
+                       }
+
+               // Go through every key on the object,
+               } else {
+                       for ( i in elems ) {
+                               value = callback( elems[ i ], i, arg );
+
+                               if ( value != null ) {
+                                       ret.push( value );
+                               }
+                       }
+               }
+
+               // Flatten any nested arrays
+               return concat.apply( [], ret );
+       },
+
+       // A global GUID counter for objects
+       guid: 1,
+
+       // Bind a function to a context, optionally partially applying any
+       // arguments.
+       proxy: function( fn, context ) {
+               var tmp, args, proxy;
+
+               if ( typeof context === "string" ) {
+                       tmp = fn[ context ];
+                       context = fn;
+                       fn = tmp;
+               }
+
+               // Quick check to determine if target is callable, in the spec
+               // this throws a TypeError, but we will just return undefined.
+               if ( !jQuery.isFunction( fn ) ) {
+                       return undefined;
+               }
+
+               // Simulated bind
+               args = slice.call( arguments, 2 );
+               proxy = function() {
+                       return fn.apply( context || this, args.concat( slice.call( arguments ) ) );
+               };
+
+               // Set the guid of unique handler to the same of original handler, so it can be removed
+               proxy.guid = fn.guid = fn.guid || jQuery.guid++;
+
+               return proxy;
+       },
+
+       now: Date.now,
+
+       // jQuery.support is not used in Core but other projects attach their
+       // properties to it so it needs to exist.
+       support: support
+} );
+
+if ( typeof Symbol === "function" ) {
+       jQuery.fn[ Symbol.iterator ] = arr[ Symbol.iterator ];
+}
+
+// Populate the class2type map
+jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ),
+function( i, name ) {
+       class2type[ "[object " + name + "]" ] = name.toLowerCase();
+} );
+
+function isArrayLike( obj ) {
+
+       // Support: real iOS 8.2 only (not reproducible in simulator)
+       // `in` check used to prevent JIT error (gh-2145)
+       // hasOwn isn't used here due to false negatives
+       // regarding Nodelist length in IE
+       var length = !!obj && "length" in obj && obj.length,
+               type = jQuery.type( obj );
+
+       if ( type === "function" || jQuery.isWindow( obj ) ) {
+               return false;
+       }
+
+       return type === "array" || length === 0 ||
+               typeof length === "number" && length > 0 && ( length - 1 ) in obj;
+}
+var Sizzle =
+/*!
+ * Sizzle CSS Selector Engine v2.3.3
+ * https://sizzlejs.com/
+ *
+ * Copyright jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2016-08-08
+ */
+(function( window ) {
+
+var i,
+       support,
+       Expr,
+       getText,
+       isXML,
+       tokenize,
+       compile,
+       select,
+       outermostContext,
+       sortInput,
+       hasDuplicate,
+
+       // Local document vars
+       setDocument,
+       document,
+       docElem,
+       documentIsHTML,
+       rbuggyQSA,
+       rbuggyMatches,
+       matches,
+       contains,
+
+       // Instance-specific data
+       expando = "sizzle" + 1 * new Date(),
+       preferredDoc = window.document,
+       dirruns = 0,
+       done = 0,
+       classCache = createCache(),
+       tokenCache = createCache(),
+       compilerCache = createCache(),
+       sortOrder = function( a, b ) {
+               if ( a === b ) {
+                       hasDuplicate = true;
+               }
+               return 0;
+       },
+
+       // Instance methods
+       hasOwn = ({}).hasOwnProperty,
+       arr = [],
+       pop = arr.pop,
+       push_native = arr.push,
+       push = arr.push,
+       slice = arr.slice,
+       // Use a stripped-down indexOf as it's faster than native
+       // https://jsperf.com/thor-indexof-vs-for/5
+       indexOf = function( list, elem ) {
+               var i = 0,
+                       len = list.length;
+               for ( ; i < len; i++ ) {
+                       if ( list[i] === elem ) {
+                               return i;
+                       }
+               }
+               return -1;
+       },
+
+       booleans = 
"checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",
+
+       // Regular expressions
+
+       // http://www.w3.org/TR/css3-selectors/#whitespace
+       whitespace = "[\\x20\\t\\r\\n\\f]",
+
+       // http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier
+       identifier = "(?:\\\\.|[\\w-]|[^\0-\\xa0])+",
+
+       // Attribute selectors: http://www.w3.org/TR/selectors/#attribute-selectors
+       attributes = "\\[" + whitespace + "*(" + identifier + ")(?:" + whitespace +
+               // Operator (capture 2)
+               "*([*^$|!~]?=)" + whitespace +
+               // "Attribute values must be CSS identifiers [capture 5] or strings [capture 3 or capture 4]"
+               "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + identifier + "))|)" + whitespace 
+
+               "*\\]",
+
+       pseudos = ":(" + identifier + ")(?:\\((" +
+               // To reduce the number of selectors needing tokenize in the preFilter, prefer arguments:
+               // 1. quoted (capture 3; capture 4 or capture 5)
+               "('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|" +
+               // 2. simple (capture 6)
+               "((?:\\\\.|[^\\\\()[\\]]|" + attributes + ")*)|" +
+               // 3. anything else (capture 2)
+               ".*" +
+               ")\\)|)",
+
+       // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding 
the latter
+       rwhitespace = new RegExp( whitespace + "+", "g" ),
+       rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ),
+
+       rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ),
+       rcombinators = new RegExp( "^" + whitespace + "*([>+~]|" + whitespace + ")" + whitespace + "*" ),
+
+       rattributeQuotes = new RegExp( "=" + whitespace + "*([^\\]'\"]*?)" + whitespace + "*\\]", "g" ),
+
+       rpseudo = new RegExp( pseudos ),
+       ridentifier = new RegExp( "^" + identifier + "$" ),
+
+       matchExpr = {
+               "ID": new RegExp( "^#(" + identifier + ")" ),
+               "CLASS": new RegExp( "^\\.(" + identifier + ")" ),
+               "TAG": new RegExp( "^(" + identifier + "|[*])" ),
+               "ATTR": new RegExp( "^" + attributes ),
+               "PSEUDO": new RegExp( "^" + pseudos ),
+               "CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+                       "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+                       "*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+               "bool": new RegExp( "^(?:" + booleans + ")$", "i" ),
+               // For use in libraries implementing .is()
+               // We use this for POS matching in `select`
+               "needsContext": new RegExp( "^" + whitespace + 
"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+                       whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+       },
+
+       rinputs = /^(?:input|select|textarea|button)$/i,
+       rheader = /^h\d$/i,
+
+       rnative = /^[^{]+\{\s*\[native \w/,
+
+       // Easily-parseable/retrievable ID or TAG or CLASS selectors
+       rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+       rsibling = /[+~]/,
+
+       // CSS escapes
+       // http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+       runescape = new RegExp( "\\\\([\\da-f]{1,6}" + whitespace + "?|(" + whitespace + ")|.)", "ig" ),
+       funescape = function( _, escaped, escapedWhitespace ) {
+               var high = "0x" + escaped - 0x10000;
+               // NaN means non-codepoint
+               // Support: Firefox<24
+               // Workaround erroneous numeric interpretation of +"0x"
+               return high !== high || escapedWhitespace ?
+                       escaped :
+                       high < 0 ?
+                               // BMP codepoint
+                               String.fromCharCode( high + 0x10000 ) :
+                               // Supplemental Plane codepoint (surrogate pair)
+                               String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+       },
+
+       // CSS string/identifier serialization
+       // https://drafts.csswg.org/cssom/#common-serializing-idioms
+       rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\0-\x1f\x7f-\uFFFF\w-]/g,
+       fcssescape = function( ch, asCodePoint ) {
+               if ( asCodePoint ) {
+
+                       // U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTER
+                       if ( ch === "\0" ) {
+                               return "\uFFFD";
+                       }
+
+                       // Control characters and (dependent upon position) numbers get escaped as code points
+                       return ch.slice( 0, -1 ) + "\\" + ch.charCodeAt( ch.length - 1 ).toString( 16 ) + " ";
+               }
+
+               // Other potentially-special ASCII characters get backslash-escaped
+               return "\\" + ch;
+       },
+
+       // Used for iframes
+       // See setDocument()
+       // Removing the function wrapper causes a "Permission Denied"
+       // error in IE
+       unloadHandler = function() {
+               setDocument();
+       },
+
+       disabledAncestor = addCombinator(
+               function( elem ) {
+                       return elem.disabled === true && ("form" in elem || "label" in elem);
+               },
+               { dir: "parentNode", next: "legend" }
+       );
+
+// Optimize for push.apply( _, NodeList )
+try {
+       push.apply(
+               (arr = slice.call( preferredDoc.childNodes )),
+               preferredDoc.childNodes
+       );
+       // Support: Android<4.0
+       // Detect silently failing push.apply
+       arr[ preferredDoc.childNodes.length ].nodeType;
+} catch ( e ) {
+       push = { apply: arr.length ?
+
+               // Leverage slice if possible
+               function( target, els ) {
+                       push_native.apply( target, slice.call(els) );
+               } :
+
+               // Support: IE<9
+               // Otherwise append directly
+               function( target, els ) {
+                       var j = target.length,
+                               i = 0;
+                       // Can't trust NodeList.length
+                       while ( (target[j++] = els[i++]) ) {}
+                       target.length = j - 1;
+               }
+       };
+}
+
+function Sizzle( selector, context, results, seed ) {
+       var m, i, elem, nid, match, groups, newSelector,
+               newContext = context && context.ownerDocument,
+
+               // nodeType defaults to 9, since context defaults to document
+               nodeType = context ? context.nodeType : 9;
+
+       results = results || [];
+
+       // Return early from calls with invalid selector or context
+       if ( typeof selector !== "string" || !selector ||
+               nodeType !== 1 && nodeType !== 9 && nodeType !== 11 ) {
+
+               return results;
+       }
+
+       // Try to shortcut find operations (as opposed to filters) in HTML documents
+       if ( !seed ) {
+
+               if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+                       setDocument( context );
+               }
+               context = context || document;
+
+               if ( documentIsHTML ) {
+
+                       // If the selector is sufficiently simple, try using a "get*By*" DOM method
+                       // (excepting DocumentFragment context, where the methods don't exist)
+                       if ( nodeType !== 11 && (match = rquickExpr.exec( selector )) ) {
+
+                               // ID selector
+                               if ( (m = match[1]) ) {
+
+                                       // Document context
+                                       if ( nodeType === 9 ) {
+                                               if ( (elem = context.getElementById( m )) ) {
+
+                                                       // Support: IE, Opera, Webkit
+                                                       // TODO: identify versions
+                                                       // getElementById can match elements by name instead 
of ID
+                                                       if ( elem.id === m ) {
+                                                               results.push( elem );
+                                                               return results;
+                                                       }
+                                               } else {
+                                                       return results;
+                                               }
+
+                                       // Element context
+                                       } else {
+
+                                               // Support: IE, Opera, Webkit
+                                               // TODO: identify versions
+                                               // getElementById can match elements by name instead of ID
+                                               if ( newContext && (elem = newContext.getElementById( m )) &&
+                                                       contains( context, elem ) &&
+                                                       elem.id === m ) {
+
+                                                       results.push( elem );
+                                                       return results;
+                                               }
+                                       }
+
+                               // Type selector
+                               } else if ( match[2] ) {
+                                       push.apply( results, context.getElementsByTagName( selector ) );
+                                       return results;
+
+                               // Class selector
+                               } else if ( (m = match[3]) && support.getElementsByClassName &&
+                                       context.getElementsByClassName ) {
+
+                                       push.apply( results, context.getElementsByClassName( m ) );
+                                       return results;
+                               }
+                       }
+
+                       // Take advantage of querySelectorAll
+                       if ( support.qsa &&
+                               !compilerCache[ selector + " " ] &&
+                               (!rbuggyQSA || !rbuggyQSA.test( selector )) ) {
+
+                               if ( nodeType !== 1 ) {
+                                       newContext = context;
+                                       newSelector = selector;
+
+                               // qSA looks outside Element context, which is not what we want
+                               // Thanks to Andrew Dupont for this workaround technique
+                               // Support: IE <=8
+                               // Exclude object elements
+                               } else if ( context.nodeName.toLowerCase() !== "object" ) {
+
+                                       // Capture the context ID, setting it first if necessary
+                                       if ( (nid = context.getAttribute( "id" )) ) {
+                                               nid = nid.replace( rcssescape, fcssescape );
+                                       } else {
+                                               context.setAttribute( "id", (nid = expando) );
+                                       }
+
+                                       // Prefix every selector in the list
+                                       groups = tokenize( selector );
+                                       i = groups.length;
+                                       while ( i-- ) {
+                                               groups[i] = "#" + nid + " " + toSelector( groups[i] );
+                                       }
+                                       newSelector = groups.join( "," );
+
+                                       // Expand context for sibling selectors
+                                       newContext = rsibling.test( selector ) && testContext( 
context.parentNode ) ||
+                                               context;
+                               }
+
+                               if ( newSelector ) {
+                                       try {
+                                               push.apply( results,
+                                                       newContext.querySelectorAll( newSelector )
+                                               );
+                                               return results;
+                                       } catch ( qsaError ) {
+                                       } finally {
+                                               if ( nid === expando ) {
+                                                       context.removeAttribute( "id" );
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       // All others
+       return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {function(string, object)} Returns the Object data after storing it on itself with
+ *     property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *     deleting the oldest entry
+ */
+function createCache() {
+       var keys = [];
+
+       function cache( key, value ) {
+               // Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+               if ( keys.push( key + " " ) > Expr.cacheLength ) {
+                       // Only keep the most recent entries
+                       delete cache[ keys.shift() ];
+               }
+               return (cache[ key + " " ] = value);
+       }
+       return cache;
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+       fn[ expando ] = true;
+       return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created element and returns a boolean result
+ */
+function assert( fn ) {
+       var el = document.createElement("fieldset");
+
+       try {
+               return !!fn( el );
+       } catch (e) {
+               return false;
+       } finally {
+               // Remove from its parent by default
+               if ( el.parentNode ) {
+                       el.parentNode.removeChild( el );
+               }
+               // release memory in IE
+               el = null;
+       }
+}
+
+/**
+ * Adds the same handler for all of the specified attrs
+ * @param {String} attrs Pipe-separated list of attributes
+ * @param {Function} handler The method that will be applied
+ */
+function addHandle( attrs, handler ) {
+       var arr = attrs.split("|"),
+               i = arr.length;
+
+       while ( i-- ) {
+               Expr.attrHandle[ arr[i] ] = handler;
+       }
+}
+
+/**
+ * Checks document order of two siblings
+ * @param {Element} a
+ * @param {Element} b
+ * @returns {Number} Returns less than 0 if a precedes b, greater than 0 if a follows b
+ */
+function siblingCheck( a, b ) {
+       var cur = b && a,
+               diff = cur && a.nodeType === 1 && b.nodeType === 1 &&
+                       a.sourceIndex - b.sourceIndex;
+
+       // Use IE sourceIndex if available on both nodes
+       if ( diff ) {
+               return diff;
+       }
+
+       // Check if b follows a
+       if ( cur ) {
+               while ( (cur = cur.nextSibling) ) {
+                       if ( cur === b ) {
+                               return -1;
+                       }
+               }
+       }
+
+       return a ? 1 : -1;
+}
+
+/**
+ * Returns a function to use in pseudos for input types
+ * @param {String} type
+ */
+function createInputPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return name === "input" && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for buttons
+ * @param {String} type
+ */
+function createButtonPseudo( type ) {
+       return function( elem ) {
+               var name = elem.nodeName.toLowerCase();
+               return (name === "input" || name === "button") && elem.type === type;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for :enabled/:disabled
+ * @param {Boolean} disabled true for :disabled; false for :enabled
+ */
+function createDisabledPseudo( disabled ) {
+
+       // Known :disabled false positives: fieldset[disabled] > legend:nth-of-type(n+2) :can-disable
+       return function( elem ) {
+
+               // Only certain elements can match :enabled or :disabled
+               // https://html.spec.whatwg.org/multipage/scripting.html#selector-enabled
+               // https://html.spec.whatwg.org/multipage/scripting.html#selector-disabled
+               if ( "form" in elem ) {
+
+                       // Check for inherited disabledness on relevant non-disabled elements:
+                       // * listed form-associated elements in a disabled fieldset
+                       //   https://html.spec.whatwg.org/multipage/forms.html#category-listed
+                       //   https://html.spec.whatwg.org/multipage/forms.html#concept-fe-disabled
+                       // * option elements in a disabled optgroup
+                       //   https://html.spec.whatwg.org/multipage/forms.html#concept-option-disabled
+                       // All such elements have a "form" property.
+                       if ( elem.parentNode && elem.disabled === false ) {
+
+                               // Option elements defer to a parent optgroup if present
+                               if ( "label" in elem ) {
+                                       if ( "label" in elem.parentNode ) {
+                                               return elem.parentNode.disabled === disabled;
+                                       } else {
+                                               return elem.disabled === disabled;
+                                       }
+                               }
+
+                               // Support: IE 6 - 11
+                               // Use the isDisabled shortcut property to check for disabled fieldset 
ancestors
+                               return elem.isDisabled === disabled ||
+
+                                       // Where there is no isDisabled, check manually
+                                       /* jshint -W018 */
+                                       elem.isDisabled !== !disabled &&
+                                               disabledAncestor( elem ) === disabled;
+                       }
+
+                       return elem.disabled === disabled;
+
+               // Try to winnow out elements that can't be disabled before trusting the disabled property.
+               // Some victims get caught in our net (label, legend, menu, track), but it shouldn't
+               // even exist on them, let alone have a boolean value.
+               } else if ( "label" in elem ) {
+                       return elem.disabled === disabled;
+               }
+
+               // Remaining elements are neither :enabled nor :disabled
+               return false;
+       };
+}
+
+/**
+ * Returns a function to use in pseudos for positionals
+ * @param {Function} fn
+ */
+function createPositionalPseudo( fn ) {
+       return markFunction(function( argument ) {
+               argument = +argument;
+               return markFunction(function( seed, matches ) {
+                       var j,
+                               matchIndexes = fn( [], seed.length, argument ),
+                               i = matchIndexes.length;
+
+                       // Match elements found at the specified indexes
+                       while ( i-- ) {
+                               if ( seed[ (j = matchIndexes[i]) ] ) {
+                                       seed[j] = !(matches[j] = seed[j]);
+                               }
+                       }
+               });
+       });
+}
+
+/**
+ * Checks a node for validity as a Sizzle context
+ * @param {Element|Object=} context
+ * @returns {Element|Object|Boolean} The input node if acceptable, otherwise a falsy value
+ */
+function testContext( context ) {
+       return context && typeof context.getElementsByTagName !== "undefined" && context;
+}
+
+// Expose support vars for convenience
+support = Sizzle.support = {};
+
+/**
+ * Detects XML nodes
+ * @param {Element|Object} elem An element or a document
+ * @returns {Boolean} True iff elem is a non-HTML XML node
+ */
+isXML = Sizzle.isXML = function( elem ) {
+       // documentElement is verified for cases where it doesn't yet exist
+       // (such as loading iframes in IE - #4833)
+       var documentElement = elem && (elem.ownerDocument || elem).documentElement;
+       return documentElement ? documentElement.nodeName !== "HTML" : false;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+       var hasCompare, subWindow,
+               doc = node ? node.ownerDocument || node : preferredDoc;
+
+       // Return early if doc is invalid or already selected
+       if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+               return document;
+       }
+
+       // Update global variables
+       document = doc;
+       docElem = document.documentElement;
+       documentIsHTML = !isXML( document );
+
+       // Support: IE 9-11, Edge
+       // Accessing iframe documents after unload throws "permission denied" errors (jQuery #13936)
+       if ( preferredDoc !== document &&
+               (subWindow = document.defaultView) && subWindow.top !== subWindow ) {
+
+               // Support: IE 11, Edge
+               if ( subWindow.addEventListener ) {
+                       subWindow.addEventListener( "unload", unloadHandler, false );
+
+               // Support: IE 9 - 10 only
+               } else if ( subWindow.attachEvent ) {
+                       subWindow.attachEvent( "onunload", unloadHandler );
+               }
+       }
+
+       /* Attributes
+       ---------------------------------------------------------------------- */
+
+       // Support: IE<8
+       // Verify that getAttribute really returns attributes and not properties
+       // (excepting IE8 booleans)
+       support.attributes = assert(function( el ) {
+               el.className = "i";
+               return !el.getAttribute("className");
+       });
+
+       /* getElement(s)By*
+       ---------------------------------------------------------------------- */
+
+       // Check if getElementsByTagName("*") returns only elements
+       support.getElementsByTagName = assert(function( el ) {
+               el.appendChild( document.createComment("") );
+               return !el.getElementsByTagName("*").length;
+       });
+
+       // Support: IE<9
+       support.getElementsByClassName = rnative.test( document.getElementsByClassName );
+
+       // Support: IE<10
+       // Check if getElementById returns elements by name
+       // The broken getElementById methods don't pick up programmatically-set names,
+       // so use a roundabout getElementsByName test
+       support.getById = assert(function( el ) {
+               docElem.appendChild( el ).id = expando;
+               return !document.getElementsByName || !document.getElementsByName( expando ).length;
+       });
+
+       // ID filter and find
+       if ( support.getById ) {
+               Expr.filter["ID"] = function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               return elem.getAttribute("id") === attrId;
+                       };
+               };
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                               var elem = context.getElementById( id );
+                               return elem ? [ elem ] : [];
+                       }
+               };
+       } else {
+               Expr.filter["ID"] =  function( id ) {
+                       var attrId = id.replace( runescape, funescape );
+                       return function( elem ) {
+                               var node = typeof elem.getAttributeNode !== "undefined" &&
+                                       elem.getAttributeNode("id");
+                               return node && node.value === attrId;
+                       };
+               };
+
+               // Support: IE 6 - 7 only
+               // getElementById is not reliable as a find shortcut
+               Expr.find["ID"] = function( id, context ) {
+                       if ( typeof context.getElementById !== "undefined" && documentIsHTML ) {
+                               var node, i, elems,
+                                       elem = context.getElementById( id );
+
+                               if ( elem ) {
+
+                                       // Verify the id attribute
+                                       node = elem.getAttributeNode("id");
+                                       if ( node && node.value === id ) {
+                                               return [ elem ];
+                                       }
+
+                                       // Fall back on getElementsByName
+                                       elems = context.getElementsByName( id );
+                                       i = 0;
+                                       while ( (elem = elems[i++]) ) {
+                                               node = elem.getAttributeNode("id");
+                                               if ( node && node.value === id ) {
+                                                       return [ elem ];
+                                               }
+                                       }
+                               }
+
+                               return [];
+                       }
+               };
+       }
+
+       // Tag
+       Expr.find["TAG"] = support.getElementsByTagName ?
+               function( tag, context ) {
+                       if ( typeof context.getElementsByTagName !== "undefined" ) {
+                               return context.getElementsByTagName( tag );
+
+                       // DocumentFragment nodes don't have gEBTN
+                       } else if ( support.qsa ) {
+                               return context.querySelectorAll( tag );
+                       }
+               } :
+
+               function( tag, context ) {
+                       var elem,
+                               tmp = [],
+                               i = 0,
+                               // By happy coincidence, a (broken) gEBTN appears on DocumentFragment nodes 
too
+                               results = context.getElementsByTagName( tag );
+
+                       // Filter out possible comments
+                       if ( tag === "*" ) {
+                               while ( (elem = results[i++]) ) {
+                                       if ( elem.nodeType === 1 ) {
+                                               tmp.push( elem );
+                                       }
+                               }
+
+                               return tmp;
+                       }
+                       return results;
+               };
+
+       // Class
+       Expr.find["CLASS"] = support.getElementsByClassName && function( className, context ) {
+               if ( typeof context.getElementsByClassName !== "undefined" && documentIsHTML ) {
+                       return context.getElementsByClassName( className );
+               }
+       };
+
+       /* QSA/matchesSelector
+       ---------------------------------------------------------------------- */
+
+       // QSA and matchesSelector support
+
+       // matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+       rbuggyMatches = [];
+
+       // qSa(:focus) reports false when true (Chrome 21)
+       // We allow this because of a bug in IE8/9 that throws an error
+       // whenever `document.activeElement` is accessed on an iframe
+       // So, we allow :focus to pass through QSA all the time to avoid the IE error
+       // See https://bugs.jquery.com/ticket/13378
+       rbuggyQSA = [];
+
+       if ( (support.qsa = rnative.test( document.querySelectorAll )) ) {
+               // Build QSA regex
+               // Regex strategy adopted from Diego Perini
+               assert(function( el ) {
+                       // Select is set to empty string on purpose
+                       // This is to test IE's treatment of not explicitly
+                       // setting a boolean content attribute,
+                       // since its presence should be enough
+                       // https://bugs.jquery.com/ticket/12359
+                       docElem.appendChild( el ).innerHTML = "<a id='" + expando + "'></a>" +
+                               "<select id='" + expando + "-\r\\' msallowcapture=''>" +
+                               "<option selected=''></option></select>";
+
+                       // Support: IE8, Opera 11-12.16
+                       // Nothing should be selected when empty strings follow ^= or $= or *=
+                       // The test attribute must be unknown in Opera but "safe" for WinRT
+                       // https://msdn.microsoft.com/en-us/library/ie/hh465388.aspx#attribute_section
+                       if ( el.querySelectorAll("[msallowcapture^='']").length ) {
+                               rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:''|\"\")" );
+                       }
+
+                       // Support: IE8
+                       // Boolean attributes and "value" are not treated correctly
+                       if ( !el.querySelectorAll("[selected]").length ) {
+                               rbuggyQSA.push( "\\[" + whitespace + "*(?:value|" + booleans + ")" );
+                       }
+
+                       // Support: Chrome<29, Android<4.4, Safari<7.0+, iOS<7.0+, PhantomJS<1.9.8+
+                       if ( !el.querySelectorAll( "[id~=" + expando + "-]" ).length ) {
+                               rbuggyQSA.push("~=");
+                       }
+
+                       // Webkit/Opera - :checked should return selected option elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       // IE8 throws error here and will not see later tests
+                       if ( !el.querySelectorAll(":checked").length ) {
+                               rbuggyQSA.push(":checked");
+                       }
+
+                       // Support: Safari 8+, iOS 8+
+                       // https://bugs.webkit.org/show_bug.cgi?id=136851
+                       // In-page `selector#id sibling-combinator selector` fails
+                       if ( !el.querySelectorAll( "a#" + expando + "+*" ).length ) {
+                               rbuggyQSA.push(".#.+[+~]");
+                       }
+               });
+
+               assert(function( el ) {
+                       el.innerHTML = "<a href='' disabled='disabled'></a>" +
+                               "<select disabled='disabled'><option/></select>";
+
+                       // Support: Windows 8 Native Apps
+                       // The type and name attributes are restricted during .innerHTML assignment
+                       var input = document.createElement("input");
+                       input.setAttribute( "type", "hidden" );
+                       el.appendChild( input ).setAttribute( "name", "D" );
+
+                       // Support: IE8
+                       // Enforce case-sensitivity of name attribute
+                       if ( el.querySelectorAll("[name=d]").length ) {
+                               rbuggyQSA.push( "name" + whitespace + "*[*^$|!~]?=" );
+                       }
+
+                       // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+                       // IE8 throws error here and will not see later tests
+                       if ( el.querySelectorAll(":enabled").length !== 2 ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Support: IE9-11+
+                       // IE's :disabled selector does not pick up the children of disabled fieldsets
+                       docElem.appendChild( el ).disabled = true;
+                       if ( el.querySelectorAll(":disabled").length !== 2 ) {
+                               rbuggyQSA.push( ":enabled", ":disabled" );
+                       }
+
+                       // Opera 10-11 does not throw on post-comma invalid pseudos
+                       el.querySelectorAll("*,:x");
+                       rbuggyQSA.push(",.*:");
+               });
+       }
+
+       if ( (support.matchesSelector = rnative.test( (matches = docElem.matches ||
+               docElem.webkitMatchesSelector ||
+               docElem.mozMatchesSelector ||
+               docElem.oMatchesSelector ||
+               docElem.msMatchesSelector) )) ) {
+
+               assert(function( el ) {
+                       // Check to see if it's possible to do matchesSelector
+                       // on a disconnected node (IE 9)
+                       support.disconnectedMatch = matches.call( el, "*" );
+
+                       // This should fail with an exception
+                       // Gecko does not error, returns false instead
+                       matches.call( el, "[s!='']:x" );
+                       rbuggyMatches.push( "!=", pseudos );
+               });
+       }
+
+       rbuggyQSA = rbuggyQSA.length && new RegExp( rbuggyQSA.join("|") );
+       rbuggyMatches = rbuggyMatches.length && new RegExp( rbuggyMatches.join("|") );
+
+       /* Contains
+       ---------------------------------------------------------------------- */
+       hasCompare = rnative.test( docElem.compareDocumentPosition );
+
+       // Element contains another
+       // Purposefully self-exclusive
+       // As in, an element does not contain itself
+       contains = hasCompare || rnative.test( docElem.contains ) ?
+               function( a, b ) {
+                       var adown = a.nodeType === 9 ? a.documentElement : a,
+                               bup = b && b.parentNode;
+                       return a === bup || !!( bup && bup.nodeType === 1 && (
+                               adown.contains ?
+                                       adown.contains( bup ) :
+                                       a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+                       ));
+               } :
+               function( a, b ) {
+                       if ( b ) {
+                               while ( (b = b.parentNode) ) {
+                                       if ( b === a ) {
+                                               return true;
+                                       }
+                               }
+                       }
+                       return false;
+               };
+
+       /* Sorting
+       ---------------------------------------------------------------------- */
+
+       // Document order sorting
+       sortOrder = hasCompare ?
+       function( a, b ) {
+
+               // Flag for duplicate removal
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               // Sort on method existence if only one input has compareDocumentPosition
+               var compare = !a.compareDocumentPosition - !b.compareDocumentPosition;
+               if ( compare ) {
+                       return compare;
+               }
+
+               // Calculate position if both inputs belong to the same document
+               compare = ( a.ownerDocument || a ) === ( b.ownerDocument || b ) ?
+                       a.compareDocumentPosition( b ) :
+
+                       // Otherwise we know they are disconnected
+                       1;
+
+               // Disconnected nodes
+               if ( compare & 1 ||
+                       (!support.sortDetached && b.compareDocumentPosition( a ) === compare) ) {
+
+                       // Choose the first element that is related to our preferred document
+                       if ( a === document || a.ownerDocument === preferredDoc && contains(preferredDoc, a) 
) {
+                               return -1;
+                       }
+                       if ( b === document || b.ownerDocument === preferredDoc && contains(preferredDoc, b) 
) {
+                               return 1;
+                       }
+
+                       // Maintain original order
+                       return sortInput ?
+                               ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+                               0;
+               }
+
+               return compare & 4 ? -1 : 1;
+       } :
+       function( a, b ) {
+               // Exit early if the nodes are identical
+               if ( a === b ) {
+                       hasDuplicate = true;
+                       return 0;
+               }
+
+               var cur,
+                       i = 0,
+                       aup = a.parentNode,
+                       bup = b.parentNode,
+                       ap = [ a ],
+                       bp = [ b ];
+
+               // Parentless nodes are either documents or disconnected
+               if ( !aup || !bup ) {
+                       return a === document ? -1 :
+                               b === document ? 1 :
+                               aup ? -1 :
+                               bup ? 1 :
+                               sortInput ?
+                               ( indexOf( sortInput, a ) - indexOf( sortInput, b ) ) :
+                               0;
+
+               // If the nodes are siblings, we can do a quick check
+               } else if ( aup === bup ) {
+                       return siblingCheck( a, b );
+               }
+
+               // Otherwise we need full lists of their ancestors for comparison
+               cur = a;
+               while ( (cur = cur.parentNode) ) {
+                       ap.unshift( cur );
+               }
+               cur = b;
+               while ( (cur = cur.parentNode) ) {
+                       bp.unshift( cur );
+               }
+
+               // Walk down the tree looking for a discrepancy
+               while ( ap[i] === bp[i] ) {
+                       i++;
+               }
+
+               return i ?
+                       // Do a sibling check if the nodes have a common ancestor
+                       siblingCheck( ap[i], bp[i] ) :
+
+                       // Otherwise nodes in our document sort first
+                       ap[i] === preferredDoc ? -1 :
+                       bp[i] === preferredDoc ? 1 :
+                       0;
+       };
+
+       return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+       return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       // Make sure that attribute selectors are quoted
+       expr = expr.replace( rattributeQuotes, "='$1']" );
+
+       if ( support.matchesSelector && documentIsHTML &&
+               !compilerCache[ expr + " " ] &&
+               ( !rbuggyMatches || !rbuggyMatches.test( expr ) ) &&
+               ( !rbuggyQSA     || !rbuggyQSA.test( expr ) ) ) {
+
+               try {
+                       var ret = matches.call( elem, expr );
+
+                       // IE 9's matchesSelector returns false on disconnected nodes
+                       if ( ret || support.disconnectedMatch ||
+                                       // As well, disconnected nodes are said to be in a document
+                                       // fragment in IE 9
+                                       elem.document && elem.document.nodeType !== 11 ) {
+                               return ret;
+                       }
+               } catch (e) {}
+       }
+
+       return Sizzle( expr, document, null, [ elem ] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+       // Set document vars if needed
+       if ( ( context.ownerDocument || context ) !== document ) {
+               setDocument( context );
+       }
+       return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+       // Set document vars if needed
+       if ( ( elem.ownerDocument || elem ) !== document ) {
+               setDocument( elem );
+       }
+
+       var fn = Expr.attrHandle[ name.toLowerCase() ],
+               // Don't get fooled by Object.prototype properties (jQuery #13807)
+               val = fn && hasOwn.call( Expr.attrHandle, name.toLowerCase() ) ?
+                       fn( elem, name, !documentIsHTML ) :
+                       undefined;
+
+       return val !== undefined ?
+               val :
+               support.attributes || !documentIsHTML ?
+                       elem.getAttribute( name ) :
+                       (val = elem.getAttributeNode(name)) && val.specified ?
+                               val.value :
+                               null;
+};
+
+Sizzle.escape = function( sel ) {
+       return (sel + "").replace( rcssescape, fcssescape );
+};
+
+Sizzle.error = function( msg ) {
+       throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+/**
+ * Document sorting and removing duplicates
+ * @param {ArrayLike} results
+ */
+Sizzle.uniqueSort = function( results ) {
+       var elem,
+               duplicates = [],
+               j = 0,
+               i = 0;
+
+       // Unless we *know* we can detect duplicates, assume their presence
+       hasDuplicate = !support.detectDuplicates;
+       sortInput = !support.sortStable && results.slice( 0 );
+       results.sort( sortOrder );
+
+       if ( hasDuplicate ) {
+               while ( (elem = results[i++]) ) {
+                       if ( elem === results[ i ] ) {
+                               j = duplicates.push( i );
+                       }
+               }
+               while ( j-- ) {
+                       results.splice( duplicates[ j ], 1 );
+               }
+       }
+
+       // Clear input after sorting to release objects
+       // See https://github.com/jquery/sizzle/pull/225
+       sortInput = null;
+
+       return results;
+};
+
+/**
+ * Utility function for retrieving the text value of an array of DOM nodes
+ * @param {Array|Element} elem
+ */
+getText = Sizzle.getText = function( elem ) {
+       var node,
+               ret = "",
+               i = 0,
+               nodeType = elem.nodeType;
+
+       if ( !nodeType ) {
+               // If no nodeType, this is expected to be an array
+               while ( (node = elem[i++]) ) {
+                       // Do not traverse comment nodes
+                       ret += getText( node );
+               }
+       } else if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) {
+               // Use textContent for elements
+               // innerText usage removed for consistency of new lines (jQuery #11153)
+               if ( typeof elem.textContent === "string" ) {
+                       return elem.textContent;
+               } else {
+                       // Traverse its children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               ret += getText( elem );
+                       }
+               }
+       } else if ( nodeType === 3 || nodeType === 4 ) {
+               return elem.nodeValue;
+       }
+       // Do not include comment or processing instruction nodes
+
+       return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+       // Can be adjusted by the user
+       cacheLength: 50,
+
+       createPseudo: markFunction,
+
+       match: matchExpr,
+
+       attrHandle: {},
+
+       find: {},
+
+       relative: {
+               ">": { dir: "parentNode", first: true },
+               " ": { dir: "parentNode" },
+               "+": { dir: "previousSibling", first: true },
+               "~": { dir: "previousSibling" }
+       },
+
+       preFilter: {
+               "ATTR": function( match ) {
+                       match[1] = match[1].replace( runescape, funescape );
+
+                       // Move the given value to match[3] whether quoted or unquoted
+                       match[3] = ( match[3] || match[4] || match[5] || "" ).replace( runescape, funescape );
+
+                       if ( match[2] === "~=" ) {
+                               match[3] = " " + match[3] + " ";
+                       }
+
+                       return match.slice( 0, 4 );
+               },
+
+               "CHILD": function( match ) {
+                       /* matches from matchExpr["CHILD"]
+                               1 type (only|nth|...)
+                               2 what (child|of-type)
+                               3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+                               4 xn-component of xn+y argument ([+-]?\d*n|)
+                               5 sign of xn-component
+                               6 x of xn-component
+                               7 sign of y-component
+                               8 y of y-component
+                       */
+                       match[1] = match[1].toLowerCase();
+
+                       if ( match[1].slice( 0, 3 ) === "nth" ) {
+                               // nth-* requires argument
+                               if ( !match[3] ) {
+                                       Sizzle.error( match[0] );
+                               }
+
+                               // numeric x and y parameters for Expr.filter.CHILD
+                               // remember that false/true cast respectively to 0/1
+                               match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === 
"even" || match[3] === "odd" ) );
+                               match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+                       // other types prohibit arguments
+                       } else if ( match[3] ) {
+                               Sizzle.error( match[0] );
+                       }
+
+                       return match;
+               },
+
+               "PSEUDO": function( match ) {
+                       var excess,
+                               unquoted = !match[6] && match[2];
+
+                       if ( matchExpr["CHILD"].test( match[0] ) ) {
+                               return null;
+                       }
+
+                       // Accept quoted arguments as-is
+                       if ( match[3] ) {
+                               match[2] = match[4] || match[5] || "";
+
+                       // Strip excess characters from unquoted arguments
+                       } else if ( unquoted && rpseudo.test( unquoted ) &&
+                               // Get excess from tokenize (recursively)
+                               (excess = tokenize( unquoted, true )) &&
+                               // advance to the next closing parenthesis
+                               (excess = unquoted.indexOf( ")", unquoted.length - excess ) - 
unquoted.length) ) {
+
+                               // excess is a negative index
+                               match[0] = match[0].slice( 0, excess );
+                               match[2] = unquoted.slice( 0, excess );
+                       }
+
+                       // Return only captures needed by the pseudo filter method (type and argument)
+                       return match.slice( 0, 3 );
+               }
+       },
+
+       filter: {
+
+               "TAG": function( nodeNameSelector ) {
+                       var nodeName = nodeNameSelector.replace( runescape, funescape ).toLowerCase();
+                       return nodeNameSelector === "*" ?
+                               function() { return true; } :
+                               function( elem ) {
+                                       return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+                               };
+               },
+
+               "CLASS": function( className ) {
+                       var pattern = classCache[ className + " " ];
+
+                       return pattern ||
+                               (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + 
whitespace + "|$)" )) &&
+                               classCache( className, function( elem ) {
+                                       return pattern.test( typeof elem.className === "string" && 
elem.className || typeof elem.getAttribute !== "undefined" && elem.getAttribute("class") || "" );
+                               });
+               },
+
+               "ATTR": function( name, operator, check ) {
+                       return function( elem ) {
+                               var result = Sizzle.attr( elem, name );
+
+                               if ( result == null ) {
+                                       return operator === "!=";
+                               }
+                               if ( !operator ) {
+                                       return true;
+                               }
+
+                               result += "";
+
+                               return operator === "=" ? result === check :
+                                       operator === "!=" ? result !== check :
+                                       operator === "^=" ? check && result.indexOf( check ) === 0 :
+                                       operator === "*=" ? check && result.indexOf( check ) > -1 :
+                                       operator === "$=" ? check && result.slice( -check.length ) === check :
+                                       operator === "~=" ? ( " " + result.replace( rwhitespace, " " ) + " " 
).indexOf( check ) > -1 :
+                                       operator === "|=" ? result === check || result.slice( 0, check.length 
+ 1 ) === check + "-" :
+                                       false;
+                       };
+               },
+
+               "CHILD": function( type, what, argument, first, last ) {
+                       var simple = type.slice( 0, 3 ) !== "nth",
+                               forward = type.slice( -4 ) !== "last",
+                               ofType = what === "of-type";
+
+                       return first === 1 && last === 0 ?
+
+                               // Shortcut for :nth-*(n)
+                               function( elem ) {
+                                       return !!elem.parentNode;
+                               } :
+
+                               function( elem, context, xml ) {
+                                       var cache, uniqueCache, outerCache, node, nodeIndex, start,
+                                               dir = simple !== forward ? "nextSibling" : "previousSibling",
+                                               parent = elem.parentNode,
+                                               name = ofType && elem.nodeName.toLowerCase(),
+                                               useCache = !xml && !ofType,
+                                               diff = false;
+
+                                       if ( parent ) {
+
+                                               // :(first|last|only)-(child|of-type)
+                                               if ( simple ) {
+                                                       while ( dir ) {
+                                                               node = elem;
+                                                               while ( (node = node[ dir ]) ) {
+                                                                       if ( ofType ?
+                                                                               node.nodeName.toLowerCase() 
=== name :
+                                                                               node.nodeType === 1 ) {
+
+                                                                               return false;
+                                                                       }
+                                                               }
+                                                               // Reverse direction for :only-* (if we 
haven't yet done so)
+                                                               start = dir = type === "only" && !start && 
"nextSibling";
+                                                       }
+                                                       return true;
+                                               }
+
+                                               start = [ forward ? parent.firstChild : parent.lastChild ];
+
+                                               // non-xml :nth-child(...) stores cache data on `parent`
+                                               if ( forward && useCache ) {
+
+                                                       // Seek `elem` from a previously-cached index
+
+                                                       // ...in a gzip-friendly way
+                                                       node = parent;
+                                                       outerCache = node[ expando ] || (node[ expando ] = 
{});
+
+                                                       // Support: IE <9 only
+                                                       // Defend against cloned attroperties (jQuery gh-1709)
+                                                       uniqueCache = outerCache[ node.uniqueID ] ||
+                                                               (outerCache[ node.uniqueID ] = {});
+
+                                                       cache = uniqueCache[ type ] || [];
+                                                       nodeIndex = cache[ 0 ] === dirruns && cache[ 1 ];
+                                                       diff = nodeIndex && cache[ 2 ];
+                                                       node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+                                                       while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+                                                               // Fallback to seeking `elem` from the start
+                                                               (diff = nodeIndex = 0) || start.pop()) ) {
+
+                                                               // When found, cache indexes on `parent` and 
break
+                                                               if ( node.nodeType === 1 && ++diff && node 
=== elem ) {
+                                                                       uniqueCache[ type ] = [ dirruns, 
nodeIndex, diff ];
+                                                                       break;
+                                                               }
+                                                       }
+
+                                               } else {
+                                                       // Use previously-cached element index if available
+                                                       if ( useCache ) {
+                                                               // ...in a gzip-friendly way
+                                                               node = elem;
+                                                               outerCache = node[ expando ] || (node[ 
expando ] = {});
+
+                                                               // Support: IE <9 only
+                                                               // Defend against cloned attroperties (jQuery 
gh-1709)
+                                                               uniqueCache = outerCache[ node.uniqueID ] ||
+                                                                       (outerCache[ node.uniqueID ] = {});
+
+                                                               cache = uniqueCache[ type ] || [];
+                                                               nodeIndex = cache[ 0 ] === dirruns && cache[ 
1 ];
+                                                               diff = nodeIndex;
+                                                       }
+
+                                                       // xml :nth-child(...)
+                                                       // or :nth-last-child(...) or 
:nth(-last)?-of-type(...)
+                                                       if ( diff === false ) {
+                                                               // Use the same loop as above to seek `elem` 
from the start
+                                                               while ( (node = ++nodeIndex && node && node[ 
dir ] ||
+                                                                       (diff = nodeIndex = 0) || 
start.pop()) ) {
+
+                                                                       if ( ( ofType ?
+                                                                               node.nodeName.toLowerCase() 
=== name :
+                                                                               node.nodeType === 1 ) &&
+                                                                               ++diff ) {
+
+                                                                               // Cache the index of each 
encountered element
+                                                                               if ( useCache ) {
+                                                                                       outerCache = node[ 
expando ] || (node[ expando ] = {});
+
+                                                                                       // Support: IE <9 only
+                                                                                       // Defend against 
cloned attroperties (jQuery gh-1709)
+                                                                                       uniqueCache = 
outerCache[ node.uniqueID ] ||
+                                                                                               (outerCache[ 
node.uniqueID ] = {});
+
+                                                                                       uniqueCache[ type ] = 
[ dirruns, diff ];
+                                                                               }
+
+                                                                               if ( node === elem ) {
+                                                                                       break;
+                                                                               }
+                                                                       }
+                                                               }
+                                                       }
+                                               }
+
+                                               // Incorporate the offset, then check against cycle size
+                                               diff -= last;
+                                               return diff === first || ( diff % first === 0 && diff / first 
= 0 );
+                                       }
+                               };
+               },
+
+               "PSEUDO": function( pseudo, argument ) {
+                       // pseudo-class names are case-insensitive
+                       // http://www.w3.org/TR/selectors/#pseudo-classes
+                       // Prioritize by case sensitivity in case custom pseudos are added with uppercase 
letters
+                       // Remember that setFilters inherits from pseudos
+                       var args,
+                               fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] ||
+                                       Sizzle.error( "unsupported pseudo: " + pseudo );
+
+                       // The user may use createPseudo to indicate that
+                       // arguments are needed to create the filter function
+                       // just as Sizzle does
+                       if ( fn[ expando ] ) {
+                               return fn( argument );
+                       }
+
+                       // But maintain support for old signatures
+                       if ( fn.length > 1 ) {
+                               args = [ pseudo, pseudo, "", argument ];
+                               return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ?
+                                       markFunction(function( seed, matches ) {
+                                               var idx,
+                                                       matched = fn( seed, argument ),
+                                                       i = matched.length;
+                                               while ( i-- ) {
+                                                       idx = indexOf( seed, matched[i] );
+                                                       seed[ idx ] = !( matches[ idx ] = matched[i] );
+                                               }
+                                       }) :
+                                       function( elem ) {
+                                               return fn( elem, 0, args );
+                                       };
+                       }
+
+                       return fn;
+               }
+       },
+
+       pseudos: {
+               // Potentially complex pseudos
+               "not": markFunction(function( selector ) {
+                       // Trim the selector passed to compile
+                       // to avoid treating leading and trailing
+                       // spaces as combinators
+                       var input = [],
+                               results = [],
+                               matcher = compile( selector.replace( rtrim, "$1" ) );
+
+                       return matcher[ expando ] ?
+                               markFunction(function( seed, matches, context, xml ) {
+                                       var elem,
+                                               unmatched = matcher( seed, null, xml, [] ),
+                                               i = seed.length;
+
+                                       // Match elements unmatched by `matcher`
+                                       while ( i-- ) {
+                                               if ( (elem = unmatched[i]) ) {
+                                                       seed[i] = !(matches[i] = elem);
+                                               }
+                                       }
+                               }) :
+                               function( elem, context, xml ) {
+                                       input[0] = elem;
+                                       matcher( input, null, xml, results );
+                                       // Don't keep the element (issue #299)
+                                       input[0] = null;
+                                       return !results.pop();
+                               };
+               }),
+
+               "has": markFunction(function( selector ) {
+                       return function( elem ) {
+                               return Sizzle( selector, elem ).length > 0;
+                       };
+               }),
+
+               "contains": markFunction(function( text ) {
+                       text = text.replace( runescape, funescape );
+                       return function( elem ) {
+                               return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( 
text ) > -1;
+                       };
+               }),
+
+               // "Whether an element is represented by a :lang() selector
+               // is based solely on the element's language value
+               // being equal to the identifier C,
+               // or beginning with the identifier C immediately followed by "-".
+               // The matching of C against the element's language value is performed case-insensitively.
+               // The identifier C does not have to be a valid language name."
+               // http://www.w3.org/TR/selectors/#lang-pseudo
+               "lang": markFunction( function( lang ) {
+                       // lang value must be a valid identifier
+                       if ( !ridentifier.test(lang || "") ) {
+                               Sizzle.error( "unsupported lang: " + lang );
+                       }
+                       lang = lang.replace( runescape, funescape ).toLowerCase();
+                       return function( elem ) {
+                               var elemLang;
+                               do {
+                                       if ( (elemLang = documentIsHTML ?
+                                               elem.lang :
+                                               elem.getAttribute("xml:lang") || elem.getAttribute("lang")) ) 
{
+
+                                               elemLang = elemLang.toLowerCase();
+                                               return elemLang === lang || elemLang.indexOf( lang + "-" ) 
=== 0;
+                                       }
+                               } while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+                               return false;
+                       };
+               }),
+
+               // Miscellaneous
+               "target": function( elem ) {
+                       var hash = window.location && window.location.hash;
+                       return hash && hash.slice( 1 ) === elem.id;
+               },
+
+               "root": function( elem ) {
+                       return elem === docElem;
+               },
+
+               "focus": function( elem ) {
+                       return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) 
&& !!(elem.type || elem.href || ~elem.tabIndex);
+               },
+
+               // Boolean properties
+               "enabled": createDisabledPseudo( false ),
+               "disabled": createDisabledPseudo( true ),
+
+               "checked": function( elem ) {
+                       // In CSS3, :checked should return both checked and selected elements
+                       // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked
+                       var nodeName = elem.nodeName.toLowerCase();
+                       return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && 
!!elem.selected);
+               },
+
+               "selected": function( elem ) {
+                       // Accessing this property makes selected-by-default
+                       // options in Safari work properly
+                       if ( elem.parentNode ) {
+                               elem.parentNode.selectedIndex;
+                       }
+
+                       return elem.selected === true;
+               },
+
+               // Contents
+               "empty": function( elem ) {
+                       // http://www.w3.org/TR/selectors/#empty-pseudo
+                       // :empty is negated by element (1) or content nodes (text: 3; cdata: 4; entity ref: 
5),
+                       //   but not by others (comment: 8; processing instruction: 7; etc.)
+                       // nodeType < 6 works because attributes (2) do not appear as children
+                       for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+                               if ( elem.nodeType < 6 ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               },
+
+               "parent": function( elem ) {
+                       return !Expr.pseudos["empty"]( elem );
+               },
+
+               // Element/input types
+               "header": function( elem ) {
+                       return rheader.test( elem.nodeName );
+               },
+
+               "input": function( elem ) {
+                       return rinputs.test( elem.nodeName );
+               },
+
+               "button": function( elem ) {
+                       var name = elem.nodeName.toLowerCase();
+                       return name === "input" && elem.type === "button" || name === "button";
+               },
+
+               "text": function( elem ) {
+                       var attr;
+                       return elem.nodeName.toLowerCase() === "input" &&
+                               elem.type === "text" &&
+
+                               // Support: IE<8
+                               // New HTML5 attribute values (e.g., "search") appear with elem.type === 
"text"
+                               ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === "text" 
);
+               },
+
+               // Position-in-collection
+               "first": createPositionalPseudo(function() {
+                       return [ 0 ];
+               }),
+
+               "last": createPositionalPseudo(function( matchIndexes, length ) {
+                       return [ length - 1 ];
+               }),
+
+               "eq": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       return [ argument < 0 ? argument + length : argument ];
+               }),
+
+               "even": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 0;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "odd": createPositionalPseudo(function( matchIndexes, length ) {
+                       var i = 1;
+                       for ( ; i < length; i += 2 ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; --i >= 0; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               }),
+
+               "gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+                       var i = argument < 0 ? argument + length : argument;
+                       for ( ; ++i < length; ) {
+                               matchIndexes.push( i );
+                       }
+                       return matchIndexes;
+               })
+       }
+};
+
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+       Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+       Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+// Easy API for creating new setFilters
+function setFilters() {}
+setFilters.prototype = Expr.filters = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+tokenize = Sizzle.tokenize = function( selector, parseOnly ) {
+       var matched, match, tokens, type,
+               soFar, groups, preFilters,
+               cached = tokenCache[ selector + " " ];
+
+       if ( cached ) {
+               return parseOnly ? 0 : cached.slice( 0 );
+       }
+
+       soFar = selector;
+       groups = [];
+       preFilters = Expr.preFilter;
+
+       while ( soFar ) {
+
+               // Comma and first run
+               if ( !matched || (match = rcomma.exec( soFar )) ) {
+                       if ( match ) {
+                               // Don't consume trailing commas as valid
+                               soFar = soFar.slice( match[0].length ) || soFar;
+                       }
+                       groups.push( (tokens = []) );
+               }
+
+               matched = false;
+
+               // Combinators
+               if ( (match = rcombinators.exec( soFar )) ) {
+                       matched = match.shift();
+                       tokens.push({
+                               value: matched,
+                               // Cast descendant combinators to space
+                               type: match[0].replace( rtrim, " " )
+                       });
+                       soFar = soFar.slice( matched.length );
+               }
+
+               // Filters
+               for ( type in Expr.filter ) {
+                       if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+                               (match = preFilters[ type ]( match ))) ) {
+                               matched = match.shift();
+                               tokens.push({
+                                       value: matched,
+                                       type: type,
+                                       matches: match
+                               });
+                               soFar = soFar.slice( matched.length );
+                       }
+               }
+
+               if ( !matched ) {
+                       break;
+               }
+       }
+
+       // Return the length of the invalid excess
+       // if we're just parsing
+       // Otherwise, throw an error or return tokens
+       return parseOnly ?
+               soFar.length :
+               soFar ?
+                       Sizzle.error( selector ) :
+                       // Cache the tokens
+                       tokenCache( selector, groups ).slice( 0 );
+};
+
+function toSelector( tokens ) {
+       var i = 0,
+               len = tokens.length,
+               selector = "";
+       for ( ; i < len; i++ ) {
+               selector += tokens[i].value;
+       }
+       return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+       var dir = combinator.dir,
+               skip = combinator.next,
+               key = skip || dir,
+               checkNonElements = base && key === "parentNode",
+               doneName = done++;
+
+       return combinator.first ?
+               // Check against closest ancestor/preceding element
+               function( elem, context, xml ) {
+                       while ( (elem = elem[ dir ]) ) {
+                               if ( elem.nodeType === 1 || checkNonElements ) {
+                                       return matcher( elem, context, xml );
+                               }
+                       }
+                       return false;
+               } :
+
+               // Check against all ancestor/preceding elements
+               function( elem, context, xml ) {
+                       var oldCache, uniqueCache, outerCache,
+                               newCache = [ dirruns, doneName ];
+
+                       // We can't set arbitrary data on XML nodes, so they don't benefit from combinator 
caching
+                       if ( xml ) {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               if ( matcher( elem, context, xml ) ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       } else {
+                               while ( (elem = elem[ dir ]) ) {
+                                       if ( elem.nodeType === 1 || checkNonElements ) {
+                                               outerCache = elem[ expando ] || (elem[ expando ] = {});
+
+                                               // Support: IE <9 only
+                                               // Defend against cloned attroperties (jQuery gh-1709)
+                                               uniqueCache = outerCache[ elem.uniqueID ] || (outerCache[ 
elem.uniqueID ] = {});
+
+                                               if ( skip && skip === elem.nodeName.toLowerCase() ) {
+                                                       elem = elem[ dir ] || elem;
+                                               } else if ( (oldCache = uniqueCache[ key ]) &&
+                                                       oldCache[ 0 ] === dirruns && oldCache[ 1 ] === 
doneName ) {
+
+                                                       // Assign to newCache so results back-propagate to 
previous elements
+                                                       return (newCache[ 2 ] = oldCache[ 2 ]);
+                                               } else {
+                                                       // Reuse newcache so results back-propagate to 
previous elements
+                                                       uniqueCache[ key ] = newCache;
+
+                                                       // A match means we're done; a fail means we have to 
keep checking
+                                                       if ( (newCache[ 2 ] = matcher( elem, context, xml )) 
) {
+                                                               return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+                       return false;
+               };
+}
+
+function elementMatcher( matchers ) {
+       return matchers.length > 1 ?
+               function( elem, context, xml ) {
+                       var i = matchers.length;
+                       while ( i-- ) {
+                               if ( !matchers[i]( elem, context, xml ) ) {
+                                       return false;
+                               }
+                       }
+                       return true;
+               } :
+               matchers[0];
+}
+
+function multipleContexts( selector, contexts, results ) {
+       var i = 0,
+               len = contexts.length;
+       for ( ; i < len; i++ ) {
+               Sizzle( selector, contexts[i], results );
+       }
+       return results;
+}
+
+function condense( unmatched, map, filter, context, xml ) {
+       var elem,
+               newUnmatched = [],
+               i = 0,
+               len = unmatched.length,
+               mapped = map != null;
+
+       for ( ; i < len; i++ ) {
+               if ( (elem = unmatched[i]) ) {
+                       if ( !filter || filter( elem, context, xml ) ) {
+                               newUnmatched.push( elem );
+                               if ( mapped ) {
+                                       map.push( i );
+                               }
+                       }
+               }
+       }
+
+       return newUnmatched;
+}
+
+function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) {
+       if ( postFilter && !postFilter[ expando ] ) {
+               postFilter = setMatcher( postFilter );
+       }
+       if ( postFinder && !postFinder[ expando ] ) {
+               postFinder = setMatcher( postFinder, postSelector );
+       }
+       return markFunction(function( seed, results, context, xml ) {
+               var temp, i, elem,
+                       preMap = [],
+                       postMap = [],
+                       preexisting = results.length,
+
+                       // Get initial elements from seed or context
+                       elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : 
context, [] ),
+
+                       // Prefilter to get matcher input, preserving a map for seed-results synchronization
+                       matcherIn = preFilter && ( seed || !selector ) ?
+                               condense( elems, preMap, preFilter, context, xml ) :
+                               elems,
+
+                       matcherOut = matcher ?
+                               // If we have a postFinder, or filtered seed, or non-seed postFilter or 
preexisting results,
+                               postFinder || ( seed ? preFilter : preexisting || postFilter ) ?
+
+                                       // ...intermediate processing is necessary
+                                       [] :
+
+                                       // ...otherwise use results directly
+                                       results :
+                               matcherIn;
+
+               // Find primary matches
+               if ( matcher ) {
+                       matcher( matcherIn, matcherOut, context, xml );
+               }
+
+               // Apply postFilter
+               if ( postFilter ) {
+                       temp = condense( matcherOut, postMap );
+                       postFilter( temp, [], context, xml );
+
+                       // Un-match failing elements by moving them back to matcherIn
+                       i = temp.length;
+                       while ( i-- ) {
+                               if ( (elem = temp[i]) ) {
+                                       matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem);
+                               }
+                       }
+               }
+
+               if ( seed ) {
+                       if ( postFinder || preFilter ) {
+                               if ( postFinder ) {
+                                       // Get the final matcherOut by condensing this intermediate into 
postFinder contexts
+                                       temp = [];
+                                       i = matcherOut.length;
+                                       while ( i-- ) {
+                                               if ( (elem = matcherOut[i]) ) {
+                                                       // Restore matcherIn since elem is not yet a final 
match
+                                                       temp.push( (matcherIn[i] = elem) );
+                                               }
+                                       }
+                                       postFinder( null, (matcherOut = []), temp, xml );
+                               }
+
+                               // Move matched elements from seed to results to keep them synchronized
+                               i = matcherOut.length;
+                               while ( i-- ) {
+                                       if ( (elem = matcherOut[i]) &&
+                                               (temp = postFinder ? indexOf( seed, elem ) : preMap[i]) > -1 
) {
+
+                                               seed[temp] = !(results[temp] = elem);
+                                       }
+                               }
+                       }
+
+               // Add elements to results, through postFinder if defined
+               } else {
+                       matcherOut = condense(
+                               matcherOut === results ?
+                                       matcherOut.splice( preexisting, matcherOut.length ) :
+                                       matcherOut
+                       );
+                       if ( postFinder ) {
+                               postFinder( null, results, matcherOut, xml );
+                       } else {
+                               push.apply( results, matcherOut );
+                       }
+               }
+       });
+}
+
+function matcherFromTokens( tokens ) {
+       var checkContext, matcher, j,
+               len = tokens.length,
+               leadingRelative = Expr.relative[ tokens[0].type ],
+               implicitRelative = leadingRelative || Expr.relative[" "],
+               i = leadingRelative ? 1 : 0,
+
+               // The foundational matcher ensures that elements are reachable from top-level context(s)
+               matchContext = addCombinator( function( elem ) {
+                       return elem === checkContext;
+               }, implicitRelative, true ),
+               matchAnyContext = addCombinator( function( elem ) {
+                       return indexOf( checkContext, elem ) > -1;
+               }, implicitRelative, true ),
+               matchers = [ function( elem, context, xml ) {
+                       var ret = ( !leadingRelative && ( xml || context !== outermostContext ) ) || (
+                               (checkContext = context).nodeType ?
+                                       matchContext( elem, context, xml ) :
+                                       matchAnyContext( elem, context, xml ) );
+                       // Avoid hanging onto element (issue #299)
+                       checkContext = null;
+                       return ret;
+               } ];
+
+       for ( ; i < len; i++ ) {
+               if ( (matcher = Expr.relative[ tokens[i].type ]) ) {
+                       matchers = [ addCombinator(elementMatcher( matchers ), matcher) ];
+               } else {
+                       matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches );
+
+                       // Return special upon seeing a positional matcher
+                       if ( matcher[ expando ] ) {
+                               // Find the next relative operator (if any) for proper handling
+                               j = ++i;
+                               for ( ; j < len; j++ ) {
+                                       if ( Expr.relative[ tokens[j].type ] ) {
+                                               break;
+                                       }
+                               }
+                               return setMatcher(
+                                       i > 1 && elementMatcher( matchers ),
+                                       i > 1 && toSelector(
+                                               // If the preceding token was a descendant combinator, insert 
an implicit any-element `*`
+                                               tokens.slice( 0, i - 1 ).concat({ value: tokens[ i - 2 ].type 
=== " " ? "*" : "" })
+                                       ).replace( rtrim, "$1" ),
+                                       matcher,
+                                       i < j && matcherFromTokens( tokens.slice( i, j ) ),
+                                       j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+                                       j < len && toSelector( tokens )
+                               );
+                       }
+                       matchers.push( matcher );
+               }
+       }
+
+       return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+       var bySet = setMatchers.length > 0,
+               byElement = elementMatchers.length > 0,
+               superMatcher = function( seed, context, xml, results, outermost ) {
+                       var elem, j, matcher,
+                               matchedCount = 0,
+                               i = "0",
+                               unmatched = seed && [],
+                               setMatched = [],
+                               contextBackup = outermostContext,
+                               // We must always have either seed elements or outermost context
+                               elems = seed || byElement && Expr.find["TAG"]( "*", outermost ),
+                               // Use integer dirruns iff this is the outermost matcher
+                               dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1),
+                               len = elems.length;
+
+                       if ( outermost ) {
+                               outermostContext = context === document || context || outermost;
+                       }
+
+                       // Add elements passing elementMatchers directly to results
+                       // Support: IE<9, Safari
+                       // Tolerate NodeList properties (IE: "length"; Safari: <number>) matching elements by 
id
+                       for ( ; i !== len && (elem = elems[i]) != null; i++ ) {
+                               if ( byElement && elem ) {
+                                       j = 0;
+                                       if ( !context && elem.ownerDocument !== document ) {
+                                               setDocument( elem );
+                                               xml = !documentIsHTML;
+                                       }
+                                       while ( (matcher = elementMatchers[j++]) ) {
+                                               if ( matcher( elem, context || document, xml) ) {
+                                                       results.push( elem );
+                                                       break;
+                                               }
+                                       }
+                                       if ( outermost ) {
+                                               dirruns = dirrunsUnique;
+                                       }
+                               }
+
+                               // Track unmatched elements for set filters
+                               if ( bySet ) {
+                                       // They will have gone through all possible matchers
+                                       if ( (elem = !matcher && elem) ) {
+                                               matchedCount--;
+                                       }
+
+                                       // Lengthen the array for every element, matched or not
+                                       if ( seed ) {
+                                               unmatched.push( elem );
+                                       }
+                               }
+                       }
+
+                       // `i` is now the count of elements visited above, and adding it to `matchedCount`
+                       // makes the latter nonnegative.
+                       matchedCount += i;
+
+                       // Apply set filters to unmatched elements
+                       // NOTE: This can be skipped if there are no unmatched elements (i.e., `matchedCount`
+                       // equals `i`), unless we didn't visit _any_ elements in the above loop because we 
have
+                       // no element matchers and no seed.
+                       // Incrementing an initially-string "0" `i` allows `i` to remain a string only in that
+                       // case, which will result in a "00" `matchedCount` that differs from `i` but is also
+                       // numerically zero.
+                       if ( bySet && i !== matchedCount ) {
+                               j = 0;
+                               while ( (matcher = setMatchers[j++]) ) {
+                                       matcher( unmatched, setMatched, context, xml );
+                               }
+
+                               if ( seed ) {
+                                       // Reintegrate element matches to eliminate the need for sorting
+                                       if ( matchedCount > 0 ) {
+                                               while ( i-- ) {
+                                                       if ( !(unmatched[i] || setMatched[i]) ) {
+                                                               setMatched[i] = pop.call( results );
+                                                       }
+                                               }
+                                       }
+
+                                       // Discard index placeholder values to get only actual matches
+                                       setMatched = condense( setMatched );
+                               }
+
+                               // Add matches to results
+                               push.apply( results, setMatched );
+
+                               // Seedless set matches succeeding multiple successful matchers stipulate 
sorting
+                               if ( outermost && !seed && setMatched.length > 0 &&
+                                       ( matchedCount + setMatchers.length ) > 1 ) {
+
+                                       Sizzle.uniqueSort( results );
+                               }
+                       }
+
+                       // Override manipulation of globals by nested matchers
+                       if ( outermost ) {
+                               dirruns = dirrunsUnique;
+                               outermostContext = contextBackup;
+                       }
+
+                       return unmatched;
+               };
+
+       return bySet ?
+               markFunction( superMatcher ) :
+               superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, match /* Internal Use Only */ ) {
+       var i,
+               setMatchers = [],
+               elementMatchers = [],
+               cached = compilerCache[ selector + " " ];
+
+       if ( !cached ) {
+               // Generate a function of recursive functions that can be used to check each element
+               if ( !match ) {
+                       match = tokenize( selector );
+               }
+               i = match.length;
+               while ( i-- ) {
+                       cached = matcherFromTokens( match[i] );
+                       if ( cached[ expando ] ) {
+                               setMatchers.push( cached );
+                       } else {
+                               elementMatchers.push( cached );
+                       }
+               }
+
+               // Cache the compiled function
+               cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) );
+
+               // Save selector and tokenization
+               cached.selector = selector;
+       }
+       return cached;
+};
+
+/**
+ * A low-level selection function that works with Sizzle's compiled
+ *  selector functions
+ * @param {String|Function} selector A selector or a pre-compiled
+ *  selector function built with Sizzle.compile
+ * @param {Element} context
+ * @param {Array} [results]
+ * @param {Array} [seed] A set of elements to match against
+ */
+select = Sizzle.select = function( selector, context, results, seed ) {
+       var i, tokens, token, type, find,
+               compiled = typeof selector === "function" && selector,
+               match = !seed && tokenize( (selector = compiled.selector || selector) );
+
+       results = results || [];
+
+       // Try to minimize operations if there is only one selector in the list and no seed
+       // (the latter of which guarantees us context)
+       if ( match.length === 1 ) {
+
+               // Reduce context if the leading compound selector is an ID
+               tokens = match[0] = match[0].slice( 0 );
+               if ( tokens.length > 2 && (token = tokens[0]).type === "ID" &&
+                               context.nodeType === 9 && documentIsHTML && Expr.relative[ tokens[1].type ] ) 
{
+
+                       context = ( Expr.find["ID"]( token.matches[0].replace(runescape, funescape), context 
) || [] )[0];
+                       if ( !context ) {
+                               return results;
+
+                       // Precompiled matchers will still verify ancestry, so step up a level
+                       } else if ( compiled ) {
+                               context = context.parentNode;
+                       }
+
+                       selector = selector.slice( tokens.shift().value.length );
+               }
+
+               // Fetch a seed set for right-to-left matching
+               i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+               while ( i-- ) {
+                       token = tokens[i];
+
+                       // Abort if we hit a combinator
+                       if ( Expr.relative[ (type = token.type) ] ) {
+                               break;
+                       }
+                       if ( (find = Expr.find[ type ]) ) {
+                               // Search, expanding context for leading sibling combinators
+                               if ( (seed = find(
+                                       token.matches[0].replace( runescape, funescape ),
+                                       rsibling.test( tokens[0].type ) && testContext( context.parentNode ) 
|| context
+                               )) ) {
+
+                                       // If seed is empty or no tokens remain, we can return early
+                                       tokens.splice( i, 1 );
+                                       selector = seed.length && toSelector( tokens );
+                                       if ( !selector ) {
+                                               push.apply( results, seed );
+                                               return results;
+                                       }
+
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       // Compile and execute a filtering function if one is not provided
+       // Provide `match` to avoid retokenization if we modified the selector above
+       ( compiled || compile( selector, match ) )(
+               seed,
+               context,
+               !documentIsHTML,
+               results,
+               !context || rsibling.test( selector ) && testContext( context.parentNode ) || context
+       );
+       return results;
+};
+
+// One-time assignments
+
+// Sort stability
+support.sortStable = expando.split("").sort( sortOrder ).join("") === expando;
+
+// Support: Chrome 14-35+
+// Always assume duplicates if they aren't passed to the comparison function
+support.detectDuplicates = !!hasDuplicate;
+
+// Initialize against the default document
+setDocument();
+
+// Support: Webkit<537.32 - Safari 6.0.3/Chrome 25 (fixed in Chrome 27)
+// Detached nodes confoundingly follow *each other*
+support.sortDetached = assert(function( el ) {
+       // Should return 1, but returns 4 (following)
+       return el.compareDocumentPosition( document.createElement("fieldset") ) & 1;
+});
+
+// Support: IE<8
+// Prevent attribute/property "interpolation"
+// https://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+if ( !assert(function( el ) {
+       el.innerHTML = "<a href='#'></a>";
+       return el.firstChild.getAttribute("href") === "#" ;
+}) ) {
+       addHandle( "type|href|height|width", function( elem, name, isXML ) {
+               if ( !isXML ) {
+                       return elem.getAttribute( name, name.toLowerCase() === "type" ? 1 : 2 );
+               }
+       });
+}
+
+// Support: IE<9
+// Use defaultValue in place of getAttribute("value")
+if ( !support.attributes || !assert(function( el ) {
+       el.innerHTML = "<input/>";
+       el.firstChild.setAttribute( "value", "" );
+       return el.firstChild.getAttribute( "value" ) === "";
+}) ) {
+       addHandle( "value", function( elem, name, isXML ) {
+               if ( !isXML && elem.nodeName.toLowerCase() === "input" ) {
+                       return elem.defaultValue;
+               }
+       });
+}
+
+// Support: IE<9
+// Use getAttributeNode to fetch booleans when getAttribute lies
+if ( !assert(function( el ) {
+       return el.getAttribute("disabled") == null;
+}) ) {
+       addHandle( booleans, function( elem, name, isXML ) {
+               var val;
+               if ( !isXML ) {
+                       return elem[ name ] === true ? name.toLowerCase() :
+                                       (val = elem.getAttributeNode( name )) && val.specified ?
+                                       val.value :
+                               null;
+               }
+       });
+}
+
+return Sizzle;
+
+})( window );
+
+
+
+jQuery.find = Sizzle;
+jQuery.expr = Sizzle.selectors;
+
+// Deprecated
+jQuery.expr[ ":" ] = jQuery.expr.pseudos;
+jQuery.uniqueSort = jQuery.unique = Sizzle.uniqueSort;
+jQuery.text = Sizzle.getText;
+jQuery.isXMLDoc = Sizzle.isXML;
+jQuery.contains = Sizzle.contains;
+jQuery.escapeSelector = Sizzle.escape;
+
+
+
+
+var dir = function( elem, dir, until ) {
+       var matched = [],
+               truncate = until !== undefined;
+
+       while ( ( elem = elem[ dir ] ) && elem.nodeType !== 9 ) {
+               if ( elem.nodeType === 1 ) {
+                       if ( truncate && jQuery( elem ).is( until ) ) {
+                               break;
+                       }
+                       matched.push( elem );
+               }
+       }
+       return matched;
+};
+
+
+var siblings = function( n, elem ) {
+       var matched = [];
+
+       for ( ; n; n = n.nextSibling ) {
+               if ( n.nodeType === 1 && n !== elem ) {
+                       matched.push( n );
+               }
+       }
+
+       return matched;
+};
+
+
+var rneedsContext = jQuery.expr.match.needsContext;
+
+
+
+function nodeName( elem, name ) {
+
+  return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase();
+
+};
+var rsingleTag = ( /^<([a-z][^\/\0>:\x20\t\r\n\f]*)[\x20\t\r\n\f]*\/?>(?:<\/\1>|)$/i );
+
+
+
+var risSimple = /^.[^:#\[\.,]*$/;
+
+// Implement the identical functionality for filter and not
+function winnow( elements, qualifier, not ) {
+       if ( jQuery.isFunction( qualifier ) ) {
+               return jQuery.grep( elements, function( elem, i ) {
+                       return !!qualifier.call( elem, i, elem ) !== not;
+               } );
+       }
+
+       // Single element
+       if ( qualifier.nodeType ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( elem === qualifier ) !== not;
+               } );
+       }
+
+       // Arraylike of elements (jQuery, arguments, Array)
+       if ( typeof qualifier !== "string" ) {
+               return jQuery.grep( elements, function( elem ) {
+                       return ( indexOf.call( qualifier, elem ) > -1 ) !== not;
+               } );
+       }
+
+       // Simple selector that can be filtered directly, removing non-Elements
+       if ( risSimple.test( qualifier ) ) {
+               return jQuery.filter( qualifier, elements, not );
+       }
+
+       // Complex selector, compare the two sets, removing non-Elements
+       qualifier = jQuery.filter( qualifier, elements );
+       return jQuery.grep( elements, function( elem ) {
+               return ( indexOf.call( qualifier, elem ) > -1 ) !== not && elem.nodeType === 1;
+       } );
+}
+
+jQuery.filter = function( expr, elems, not ) {
+       var elem = elems[ 0 ];
+
+       if ( not ) {
+               expr = ":not(" + expr + ")";
+       }
+
+       if ( elems.length === 1 && elem.nodeType === 1 ) {
+               return jQuery.find.matchesSelector( elem, expr ) ? [ elem ] : [];
+       }
+
+       return jQuery.find.matches( expr, jQuery.grep( elems, function( elem ) {
+               return elem.nodeType === 1;
+       } ) );
+};
+
+jQuery.fn.extend( {
+       find: function( selector ) {
+               var i, ret,
+                       len = this.length,
+                       self = this;
+
+               if ( typeof selector !== "string" ) {
+                       return this.pushStack( jQuery( selector ).filter( function() {
+                               for ( i = 0; i < len; i++ ) {
+                                       if ( jQuery.contains( self[ i ], this ) ) {
+                                               return true;
+                                       }
+                               }
+                       } ) );
+               }
+
+               ret = this.pushStack( [] );
+
+               for ( i = 0; i < len; i++ ) {
+                       jQuery.find( selector, self[ i ], ret );
+               }
+
+               return len > 1 ? jQuery.uniqueSort( ret ) : ret;
+       },
+       filter: function( selector ) {
+               return this.pushStack( winnow( this, selector || [], false ) );
+       },
+       not: function( selector ) {
+               return this.pushStack( winnow( this, selector || [], true ) );
+       },
+       is: function( selector ) {
+               return !!winnow(
+                       this,
+
+                       // If this is a positional/relative selector, check membership in the returned set
+                       // so $("p:first").is("p:last") won't return true for a doc with two "p".
+                       typeof selector === "string" && rneedsContext.test( selector ) ?
+                               jQuery( selector ) :
+                               selector || [],
+                       false
+               ).length;
+       }
+} );
+
+
+// Initialize a jQuery object
+
+
+// A central reference to the root jQuery(document)
+var rootjQuery,
+
+       // A simple way to check for HTML strings
+       // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
+       // Strict HTML recognition (#11290: must start with <)
+       // Shortcut simple #id case for speed
+       rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]+))$/,
+
+       init = jQuery.fn.init = function( selector, context, root ) {
+               var match, elem;
+
+               // HANDLE: $(""), $(null), $(undefined), $(false)
+               if ( !selector ) {
+                       return this;
+               }
+
+               // Method init() accepts an alternate rootjQuery
+               // so migrate can support jQuery.sub (gh-2101)
+               root = root || rootjQuery;
+
+               // Handle HTML strings
+               if ( typeof selector === "string" ) {
+                       if ( selector[ 0 ] === "<" &&
+                               selector[ selector.length - 1 ] === ">" &&
+                               selector.length >= 3 ) {
+
+                               // Assume that strings that start and end with <> are HTML and skip the regex 
check
+                               match = [ null, selector, null ];
+
+                       } else {
+                               match = rquickExpr.exec( selector );
+                       }
+
+                       // Match html or make sure no context is specified for #id
+                       if ( match && ( match[ 1 ] || !context ) ) {
+
+                               // HANDLE: $(html) -> $(array)
+                               if ( match[ 1 ] ) {
+                                       context = context instanceof jQuery ? context[ 0 ] : context;
+
+                                       // Option to run scripts is true for back-compat
+                                       // Intentionally let the error be thrown if parseHTML is not present
+                                       jQuery.merge( this, jQuery.parseHTML(
+                                               match[ 1 ],
+                                               context && context.nodeType ? context.ownerDocument || 
context : document,
+                                               true
+                                       ) );
+
+                                       // HANDLE: $(html, props)
+                                       if ( rsingleTag.test( match[ 1 ] ) && jQuery.isPlainObject( context ) 
) {
+                                               for ( match in context ) {
+
+                                                       // Properties of context are called as methods if 
possible
+                                                       if ( jQuery.isFunction( this[ match ] ) ) {
+                                                               this[ match ]( context[ match ] );
+
+                                                       // ...and otherwise set as attributes
+                                                       } else {
+                                                               this.attr( match, context[ match ] );
+                                                       }
+                                               }
+                                       }
+
+                                       return this;
+
+                               // HANDLE: $(#id)
+                               } else {
+                                       elem = document.getElementById( match[ 2 ] );
+
+                                       if ( elem ) {
+
+                                               // Inject the element directly into the jQuery object
+                                               this[ 0 ] = elem;
+                                               this.length = 1;
+                                       }
+                                       return this;
+                               }
+
+                       // HANDLE: $(expr, $(...))
+                       } else if ( !context || context.jquery ) {
+                               return ( context || root ).find( selector );
+
+                       // HANDLE: $(expr, context)
+                       // (which is just equivalent to: $(context).find(expr)
+                       } else {
+                               return this.constructor( context ).find( selector );
+                       }
+
+               // HANDLE: $(DOMElement)
+               } else if ( selector.nodeType ) {
+                       this[ 0 ] = selector;
+                       this.length = 1;
+                       return this;
+
+               // HANDLE: $(function)
+               // Shortcut for document ready
+               } else if ( jQuery.isFunction( selector ) ) {
+                       return root.ready !== undefined ?
+                               root.ready( selector ) :
+
+                               // Execute immediately if ready is not present
+                               selector( jQuery );
+               }
+
+               return jQuery.makeArray( selector, this );
+       };
+
+// Give the init function the jQuery prototype for later instantiation
+init.prototype = jQuery.fn;
+
+// Initialize central reference
+rootjQuery = jQuery( document );
+
+
+var rparentsprev = /^(?:parents|prev(?:Until|All))/,
+
+       // Methods guaranteed to produce a unique set when starting from a unique set
+       guaranteedUnique = {
+               children: true,
+               contents: true,
+               next: true,
+               prev: true
+       };
+
+jQuery.fn.extend( {
+       has: function( target ) {
+               var targets = jQuery( target, this ),
+                       l = targets.length;
+
+               return this.filter( function() {
+                       var i = 0;
+                       for ( ; i < l; i++ ) {
+                               if ( jQuery.contains( this, targets[ i ] ) ) {
+                                       return true;
+                               }
+                       }
+               } );
+       },
+
+       closest: function( selectors, context ) {
+               var cur,
+                       i = 0,
+                       l = this.length,
+                       matched = [],
+                       targets = typeof selectors !== "string" && jQuery( selectors );
+
+               // Positional selectors never match, since there's no _selection_ context
+               if ( !rneedsContext.test( selectors ) ) {
+                       for ( ; i < l; i++ ) {
+                               for ( cur = this[ i ]; cur && cur !== context; cur = cur.parentNode ) {
+
+                                       // Always skip document fragments
+                                       if ( cur.nodeType < 11 && ( targets ?
+                                               targets.index( cur ) > -1 :
+
+                                               // Don't pass non-elements to Sizzle
+                                               cur.nodeType === 1 &&
+                                                       jQuery.find.matchesSelector( cur, selectors ) ) ) {
+
+                                               matched.push( cur );
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return this.pushStack( matched.length > 1 ? jQuery.uniqueSort( matched ) : matched );
+       },
+
+       // Determine the position of an element within the set
+       index: function( elem ) {
+
+               // No argument, return index in parent
+               if ( !elem ) {
+                       return ( this[ 0 ] && this[ 0 ].parentNode ) ? this.first().prevAll().length : -1;
+               }
+
+               // Index in selector
+               if ( typeof elem === "string" ) {
+                       return indexOf.call( jQuery( elem ), this[ 0 ] );
+               }
+
+               // Locate the position of the desired element
+               return indexOf.call( this,
+
+                       // If it receives a jQuery object, the first element is used
+                       elem.jquery ? elem[ 0 ] : elem
+               );
+       },
+
+       add: function( selector, context ) {
+               return this.pushStack(
+                       jQuery.uniqueSort(
+                               jQuery.merge( this.get(), jQuery( selector, context ) )
+                       )
+               );
+       },
+
+       addBack: function( selector ) {
+               return this.add( selector == null ?
+                       this.prevObject : this.prevObject.filter( selector )
+               );
+       }
+} );
+
+function sibling( cur, dir ) {
+       while ( ( cur = cur[ dir ] ) && cur.nodeType !== 1 ) {}
+       return cur;
+}
+
+jQuery.each( {
+       parent: function( elem ) {
+               var parent = elem.parentNode;
+               return parent && parent.nodeType !== 11 ? parent : null;
+       },
+       parents: function( elem ) {
+               return dir( elem, "parentNode" );
+       },
+       parentsUntil: function( elem, i, until ) {
+               return dir( elem, "parentNode", until );
+       },
+       next: function( elem ) {
+               return sibling( elem, "nextSibling" );
+       },
+       prev: function( elem ) {
+               return sibling( elem, "previousSibling" );
+       },
+       nextAll: function( elem ) {
+               return dir( elem, "nextSibling" );
+       },
+       prevAll: function( elem ) {
+               return dir( elem, "previousSibling" );
+       },
+       nextUntil: function( elem, i, until ) {
+               return dir( elem, "nextSibling", until );
+       },
+       prevUntil: function( elem, i, until ) {
+               return dir( elem, "previousSibling", until );
+       },
+       siblings: function( elem ) {
+               return siblings( ( elem.parentNode || {} ).firstChild, elem );
+       },
+       children: function( elem ) {
+               return siblings( elem.firstChild );
+       },
+       contents: function( elem ) {
+        if ( nodeName( elem, "iframe" ) ) {
+            return elem.contentDocument;
+        }
+
+        // Support: IE 9 - 11 only, iOS 7 only, Android Browser <=4.3 only
+        // Treat the template element as a regular one in browsers that
+        // don't support it.
+        if ( nodeName( elem, "template" ) ) {
+            elem = elem.content || elem;
+        }
+
+        return jQuery.merge( [], elem.childNodes );
+       }
+}, function( name, fn ) {
+       jQuery.fn[ name ] = function( until, selector ) {
+               var matched = jQuery.map( this, fn, until );
+
+               if ( name.slice( -5 ) !== "Until" ) {
+                       selector = until;
+               }
+
+               if ( selector && typeof selector === "string" ) {
+                       matched = jQuery.filter( selector, matched );
+               }
+
+               if ( this.length > 1 ) {
+
+                       // Remove duplicates
+                       if ( !guaranteedUnique[ name ] ) {
+                               jQuery.uniqueSort( matched );
+                       }
+
+                       // Reverse order for parents* and prev-derivatives
+                       if ( rparentsprev.test( name ) ) {
+                               matched.reverse();
+                       }
+               }
+
+               return this.pushStack( matched );
+       };
+} );
+var rnothtmlwhite = ( /[^\x20\t\r\n\f]+/g );
+
+
+
+// Convert String-formatted options into Object-formatted ones
+function createOptions( options ) {
+       var object = {};
+       jQuery.each( options.match( rnothtmlwhite ) || [], function( _, flag ) {
+               object[ flag ] = true;
+       } );
+       return object;
+}
+
+/*
+ * Create a callback list using the following parameters:
+ *
+ *     options: an optional list of space-separated options that will change how
+ *                     the callback list behaves or a more traditional option object
+ *
+ * By default a callback list will act like an event callback list and can be
+ * "fired" multiple times.
+ *
+ * Possible options:
+ *
+ *     once:                   will ensure the callback list can only be fired once (like a Deferred)
+ *
+ *     memory:                 will keep track of previous values and will call any callback added
+ *                                     after the list has been fired right away with the latest "memorized"
+ *                                     values (like a Deferred)
+ *
+ *     unique:                 will ensure a callback can only be added once (no duplicate in the list)
+ *
+ *     stopOnFalse:    interrupt callings when a callback returns false
+ *
+ */
+jQuery.Callbacks = function( options ) {
+
+       // Convert options from String-formatted to Object-formatted if needed
+       // (we check in cache first)
+       options = typeof options === "string" ?
+               createOptions( options ) :
+               jQuery.extend( {}, options );
+
+       var // Flag to know if list is currently firing
+               firing,
+
+               // Last fire value for non-forgettable lists
+               memory,
+
+               // Flag to know if list was already fired
+               fired,
+
+               // Flag to prevent firing
+               locked,
+
+               // Actual callback list
+               list = [],
+
+               // Queue of execution data for repeatable lists
+               queue = [],
+
+               // Index of currently firing callback (modified by add/remove as needed)
+               firingIndex = -1,
+
+               // Fire callbacks
+               fire = function() {
+
+                       // Enforce single-firing
+                       locked = locked || options.once;
+
+                       // Execute callbacks for all pending executions,
+                       // respecting firingIndex overrides and runtime changes
+                       fired = firing = true;
+                       for ( ; queue.length; firingIndex = -1 ) {
+                               memory = queue.shift();
+                               while ( ++firingIndex < list.length ) {
+
+                                       // Run callback and check for early termination
+                                       if ( list[ firingIndex ].apply( memory[ 0 ], memory[ 1 ] ) === false 
&&
+                                               options.stopOnFalse ) {
+
+                                               // Jump to end and forget the data so .add doesn't re-fire
+                                               firingIndex = list.length;
+                                               memory = false;
+                                       }
+                               }
+                       }
+
+                       // Forget the data if we're done with it
+                       if ( !options.memory ) {
+                               memory = false;
+                       }
+
+                       firing = false;
+
+                       // Clean up if we're done firing for good
+                       if ( locked ) {
+
+                               // Keep an empty list if we have data for future add calls
+                               if ( memory ) {
+                                       list = [];
+
+                               // Otherwise, this object is spent
+                               } else {
+                                       list = "";
+                               }
+                       }
+               },
+
+               // Actual Callbacks object
+               self = {
+
+                       // Add a callback or a collection of callbacks to the list
+                       add: function() {
+                               if ( list ) {
+
+                                       // If we have memory from a past run, we should fire after adding
+                                       if ( memory && !firing ) {
+                                               firingIndex = list.length - 1;
+                                               queue.push( memory );
+                                       }
+
+                                       ( function add( args ) {
+                                               jQuery.each( args, function( _, arg ) {
+                                                       if ( jQuery.isFunction( arg ) ) {
+                                                               if ( !options.unique || !self.has( arg ) ) {
+                                                                       list.push( arg );
+                                                               }
+                                                       } else if ( arg && arg.length && jQuery.type( arg ) 
!== "string" ) {
+
+                                                               // Inspect recursively
+                                                               add( arg );
+                                                       }
+                                               } );
+                                       } )( arguments );
+
+                                       if ( memory && !firing ) {
+                                               fire();
+                                       }
+                               }
+                               return this;
+                       },
+
+                       // Remove a callback from the list
+                       remove: function() {
+                               jQuery.each( arguments, function( _, arg ) {
+                                       var index;
+                                       while ( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) {
+                                               list.splice( index, 1 );
+
+                                               // Handle firing indexes
+                                               if ( index <= firingIndex ) {
+                                                       firingIndex--;
+                                               }
+                                       }
+                               } );
+                               return this;
+                       },
+
+                       // Check if a given callback is in the list.
+                       // If no argument is given, return whether or not list has callbacks attached.
+                       has: function( fn ) {
+                               return fn ?
+                                       jQuery.inArray( fn, list ) > -1 :
+                                       list.length > 0;
+                       },
+
+                       // Remove all callbacks from the list
+                       empty: function() {
+                               if ( list ) {
+                                       list = [];
+                               }
+                               return this;
+                       },
+
+                       // Disable .fire and .add
+                       // Abort any current/pending executions
+                       // Clear all callbacks and values
+                       disable: function() {
+                               locked = queue = [];
+                               list = memory = "";
+                               return this;
+                       },
+                       disabled: function() {
+                               return !list;
+                       },
+
+                       // Disable .fire
+                       // Also disable .add unless we have memory (since it would have no effect)
+                       // Abort any pending executions
+                       lock: function() {
+                               locked = queue = [];
+                               if ( !memory && !firing ) {
+                                       list = memory = "";
+                               }
+                               return this;
+                       },
+                       locked: function() {
+                               return !!locked;
+                       },
+
+                       // Call all callbacks with the given context and arguments
+                       fireWith: function( context, args ) {
+                               if ( !locked ) {
+                                       args = args || [];
+                                       args = [ context, args.slice ? args.slice() : args ];
+                                       queue.push( args );
+                                       if ( !firing ) {
+                                               fire();
+                                       }
+                               }
+                               return this;
+                       },
+
+                       // Call all the callbacks with the given arguments
+                       fire: function() {
+                               self.fireWith( this, arguments );
+                               return this;
+                       },
+
+                       // To know if the callbacks have already been called at least once
+                       fired: function() {
+                               return !!fired;
+                       }
+               };
+
+       return self;
+};
+
+
+function Identity( v ) {
+       return v;
+}
+function Thrower( ex ) {
+       throw ex;
+}
+
+function adoptValue( value, resolve, reject, noValue ) {
+       var method;
+
+       try {
+
+               // Check for promise aspect first to privilege synchronous behavior
+               if ( value && jQuery.isFunction( ( method = value.promise ) ) ) {
+                       method.call( value ).done( resolve ).fail( reject );
+
+               // Other thenables
+               } else if ( value && jQuery.isFunction( ( method = value.then ) ) ) {
+                       method.call( value, resolve, reject );
+
+               // Other non-thenables
+               } else {
+
+                       // Control `resolve` arguments by letting Array#slice cast boolean `noValue` to 
integer:
+                       // * false: [ value ].slice( 0 ) => resolve( value )
+                       // * true: [ value ].slice( 1 ) => resolve()
+                       resolve.apply( undefined, [ value ].slice( noValue ) );
+               }
+
+       // For Promises/A+, convert exceptions into rejections
+       // Since jQuery.when doesn't unwrap thenables, we can skip the extra checks appearing in
+       // Deferred#then to conditionally suppress rejection.
+       } catch ( value ) {
+
+               // Support: Android 4.0 only
+               // Strict mode functions invoked without .call/.apply get global-object context
+               reject.apply( undefined, [ value ] );
+       }
+}
+
+jQuery.extend( {
+
+       Deferred: function( func ) {
+               var tuples = [
+
+                               // action, add listener, callbacks,
+                               // ... .then handlers, argument index, [final state]
+                               [ "notify", "progress", jQuery.Callbacks( "memory" ),
+                                       jQuery.Callbacks( "memory" ), 2 ],
+                               [ "resolve", "done", jQuery.Callbacks( "once memory" ),
+                                       jQuery.Callbacks( "once memory" ), 0, "resolved" ],
+                               [ "reject", "fail", jQuery.Callbacks( "once memory" ),
+                                       jQuery.Callbacks( "once memory" ), 1, "rejected" ]
+                       ],
+                       state = "pending",
+                       promise = {
+                               state: function() {
+                                       return state;
+                               },
+                               always: function() {
+                                       deferred.done( arguments ).fail( arguments );
+                                       return this;
+                               },
+                               "catch": function( fn ) {
+                                       return promise.then( null, fn );
+                               },
+
+                               // Keep pipe for back-compat
+                               pipe: function( /* fnDone, fnFail, fnProgress */ ) {
+                                       var fns = arguments;
+
+                                       return jQuery.Deferred( function( newDefer ) {
+                                               jQuery.each( tuples, function( i, tuple ) {
+
+                                                       // Map tuples (progress, done, fail) to arguments 
(done, fail, progress)
+                                                       var fn = jQuery.isFunction( fns[ tuple[ 4 ] ] ) && 
fns[ tuple[ 4 ] ];
+
+                                                       // deferred.progress(function() { bind to newDefer or 
newDefer.notify })
+                                                       // deferred.done(function() { bind to newDefer or 
newDefer.resolve })
+                                                       // deferred.fail(function() { bind to newDefer or 
newDefer.reject })
+                                                       deferred[ tuple[ 1 ] ]( function() {
+                                                               var returned = fn && fn.apply( this, 
arguments );
+                                                               if ( returned && jQuery.isFunction( 
returned.promise ) ) {
+                                                                       returned.promise()
+                                                                               .progress( newDefer.notify )
+                                                                               .done( newDefer.resolve )
+                                                                               .fail( newDefer.reject );
+                                                               } else {
+                                                                       newDefer[ tuple[ 0 ] + "With" ](
+                                                                               this,
+                                                                               fn ? [ returned ] : arguments
+                                                                       );
+                                                               }
+                                                       } );
+                                               } );
+                                               fns = null;
+                                       } ).promise();
+                               },
+                               then: function( onFulfilled, onRejected, onProgress ) {
+                                       var maxDepth = 0;
+                                       function resolve( depth, deferred, handler, special ) {
+                                               return function() {
+                                                       var that = this,
+                                                               args = arguments,
+                                                               mightThrow = function() {
+                                                                       var returned, then;
+
+                                                                       // Support: Promises/A+ section 
2.3.3.3.3
+                                                                       // https://promisesaplus.com/#point-59
+                                                                       // Ignore double-resolution attempts
+                                                                       if ( depth < maxDepth ) {
+                                                                               return;
+                                                                       }
+
+                                                                       returned = handler.apply( that, args 
);
+
+                                                                       // Support: Promises/A+ section 2.3.1
+                                                                       // https://promisesaplus.com/#point-48
+                                                                       if ( returned === deferred.promise() 
) {
+                                                                               throw new TypeError( 
"Thenable self-resolution" );
+                                                                       }
+
+                                                                       // Support: Promises/A+ sections 
2.3.3.1, 3.5
+                                                                       // https://promisesaplus.com/#point-54
+                                                                       // https://promisesaplus.com/#point-75
+                                                                       // Retrieve `then` only once
+                                                                       then = returned &&
+
+                                                                               // Support: Promises/A+ 
section 2.3.4
+                                                                               // 
https://promisesaplus.com/#point-64
+                                                                               // Only check objects and 
functions for thenability
+                                                                               ( typeof returned === 
"object" ||
+                                                                                       typeof returned === 
"function" ) &&
+                                                                               returned.then;
+
+                                                                       // Handle a returned thenable
+                                                                       if ( jQuery.isFunction( then ) ) {
+
+                                                                               // Special processors 
(notify) just wait for resolution
+                                                                               if ( special ) {
+                                                                                       then.call(
+                                                                                               returned,
+                                                                                               resolve( 
maxDepth, deferred, Identity, special ),
+                                                                                               resolve( 
maxDepth, deferred, Thrower, special )
+                                                                                       );
+
+                                                                               // Normal processors 
(resolve) also hook into progress
+                                                                               } else {
+
+                                                                                       // ...and disregard 
older resolution values
+                                                                                       maxDepth++;
+
+                                                                                       then.call(
+                                                                                               returned,
+                                                                                               resolve( 
maxDepth, deferred, Identity, special ),
+                                                                                               resolve( 
maxDepth, deferred, Thrower, special ),
+                                                                                               resolve( 
maxDepth, deferred, Identity,
+                                                                                                       
deferred.notifyWith )
+                                                                                       );
+                                                                               }
+
+                                                                       // Handle all other returned values
+                                                                       } else {
+
+                                                                               // Only substitute handlers 
pass on context
+                                                                               // and multiple values 
(non-spec behavior)
+                                                                               if ( handler !== Identity ) {
+                                                                                       that = undefined;
+                                                                                       args = [ returned ];
+                                                                               }
+
+                                                                               // Process the value(s)
+                                                                               // Default process is resolve
+                                                                               ( special || 
deferred.resolveWith )( that, args );
+                                                                       }
+                                                               },
+
+                                                               // Only normal processors (resolve) catch and 
reject exceptions
+                                                               process = special ?
+                                                                       mightThrow :
+                                                                       function() {
+                                                                               try {
+                                                                                       mightThrow();
+                                                                               } catch ( e ) {
+
+                                                                                       if ( 
jQuery.Deferred.exceptionHook ) {
+                                                                                               
jQuery.Deferred.exceptionHook( e,
+                                                                                                       
process.stackTrace );
+                                                                                       }
+
+                                                                                       // Support: 
Promises/A+ section 2.3.3.3.4.1
+                                                                                       // 
https://promisesaplus.com/#point-61
+                                                                                       // Ignore 
post-resolution exceptions
+                                                                                       if ( depth + 1 >= 
maxDepth ) {
+
+                                                                                               // Only 
substitute handlers pass on context
+                                                                                               // and 
multiple values (non-spec behavior)
+                                                                                               if ( handler 
!== Thrower ) {
+                                                                                                       that 
= undefined;
+                                                                                                       args 
= [ e ];
+                                                                                               }
+
+                                                                                               
deferred.rejectWith( that, args );
+                                                                                       }
+                                                                               }
+                                                                       };
+
+                                                       // Support: Promises/A+ section 2.3.3.3.1
+                                                       // https://promisesaplus.com/#point-57
+                                                       // Re-resolve promises immediately to dodge false 
rejection from
+                                                       // subsequent errors
+                                                       if ( depth ) {
+                                                               process();
+                                                       } else {
+
+                                                               // Call an optional hook to record the stack, 
in case of exception
+                                                               // since it's otherwise lost when execution 
goes async
+                                                               if ( jQuery.Deferred.getStackHook ) {
+                                                                       process.stackTrace = 
jQuery.Deferred.getStackHook();
+                                                               }
+                                                               window.setTimeout( process );
+                                                       }
+                                               };
+                                       }
+
+                                       return jQuery.Deferred( function( newDefer ) {
+
+                                               // progress_handlers.add( ... )
+                                               tuples[ 0 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onProgress ) ?
+                                                                       onProgress :
+                                                                       Identity,
+                                                               newDefer.notifyWith
+                                                       )
+                                               );
+
+                                               // fulfilled_handlers.add( ... )
+                                               tuples[ 1 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onFulfilled ) ?
+                                                                       onFulfilled :
+                                                                       Identity
+                                                       )
+                                               );
+
+                                               // rejected_handlers.add( ... )
+                                               tuples[ 2 ][ 3 ].add(
+                                                       resolve(
+                                                               0,
+                                                               newDefer,
+                                                               jQuery.isFunction( onRejected ) ?
+                                                                       onRejected :
+                                                                       Thrower
+                                                       )
+                                               );
+                                       } ).promise();
+                               },
+
+                               // Get a promise for this deferred
+                               // If obj is provided, the promise aspect is added to the object
+                               promise: function( obj ) {
+                                       return obj != null ? jQuery.extend( obj, promise ) : promise;
+                               }
+                       },
+                       deferred = {};
+
+               // Add list-specific methods
+               jQuery.each( tuples, function( i, tuple ) {
+                       var list = tuple[ 2 ],
+                               stateString = tuple[ 5 ];
+
+                       // promise.progress = list.add
+                       // promise.done = list.add
+                       // promise.fail = list.add
+                       promise[ tuple[ 1 ] ] = list.add;
+
+                       // Handle state
+                       if ( stateString ) {
+                               list.add(
+                                       function() {
+
+                                               // state = "resolved" (i.e., fulfilled)
+                                               // state = "rejected"
+                                               state = stateString;
+                                       },
+
+                                       // rejected_callbacks.disable
+                                       // fulfilled_callbacks.disable
+                                       tuples[ 3 - i ][ 2 ].disable,
+
+                                       // progress_callbacks.lock
+                                       tuples[ 0 ][ 2 ].lock
+                               );
+                       }
+
+                       // progress_handlers.fire
+                       // fulfilled_handlers.fire
+                       // rejected_handlers.fire
+                       list.add( tuple[ 3 ].fire );
+
+                       // deferred.notify = function() { deferred.notifyWith(...) }
+                       // deferred.resolve = function() { deferred.resolveWith(...) }
+                       // deferred.reject = function() { deferred.rejectWith(...) }
+                       deferred[ tuple[ 0 ] ] = function() {
+                               deferred[ tuple[ 0 ] + "With" ]( this === deferred ? undefined : this, 
arguments );
+                               return this;
+                       };
+
+                       // deferred.notifyWith = list.fireWith
+                       // deferred.resolveWith = list.fireWith
+                       // deferred.rejectWith = list.fireWith
+                       deferred[ tuple[ 0 ] + "With" ] = list.fireWith;
+               } );
+
+               // Make the deferred a promise
+               promise.promise( deferred );
+
+               // Call given func if any
+               if ( func ) {
+                       func.call( deferred, deferred );
+               }
+
+               // All done!
+               return deferred;
+       },
+
+       // Deferred helper
+       when: function( singleValue ) {
+               var
+
+                       // count of uncompleted subordinates
+                       remaining = arguments.length,
+
+                       // count of unprocessed arguments
+                       i = remaining,
+
+                       // subordinate fulfillment data
+                       resolveContexts = Array( i ),
+                       resolveValues = slice.call( arguments ),
+
+                       // the master Deferred
+                       master = jQuery.Deferred(),
+
+                       // subordinate callback factory
+                       updateFunc = function( i ) {
+                               return function( value ) {
+                                       resolveContexts[ i ] = this;
+                                       resolveValues[ i ] = arguments.length > 1 ? slice.call( arguments ) : 
value;
+                                       if ( !( --remaining ) ) {
+                                               master.resolveWith( resolveContexts, resolveValues );
+                                       }
+                               };
+                       };
+
+               // Single- and empty arguments are adopted like Promise.resolve
+               if ( remaining <= 1 ) {
+                       adoptValue( singleValue, master.done( updateFunc( i ) ).resolve, master.reject,
+                               !remaining );
+
+                       // Use .then() to unwrap secondary thenables (cf. gh-3000)
+                       if ( master.state() === "pending" ||
+                               jQuery.isFunction( resolveValues[ i ] && resolveValues[ i ].then ) ) {
+
+                               return master.then();
+                       }
+               }
+
+               // Multiple arguments are aggregated like Promise.all array elements
+               while ( i-- ) {
+                       adoptValue( resolveValues[ i ], updateFunc( i ), master.reject );
+               }
+
+               return master.promise();
+       }
+} );
+
+
+// These usually indicate a programmer mistake during development,
+// warn about them ASAP rather than swallowing them by default.
+var rerrorNames = /^(Eval|Internal|Range|Reference|Syntax|Type|URI)Error$/;
+
+jQuery.Deferred.exceptionHook = function( error, stack ) {
+
+       // Support: IE 8 - 9 only
+       // Console exists when dev tools are open, which can happen at any time
+       if ( window.console && window.console.warn && error && rerrorNames.test( error.name ) ) {
+               window.console.warn( "jQuery.Deferred exception: " + error.message, error.stack, stack );
+       }
+};
+
+
+
+
+jQuery.readyException = function( error ) {
+       window.setTimeout( function() {
+               throw error;
+       } );
+};
+
+
+
+
+// The deferred used on DOM ready
+var readyList = jQuery.Deferred();
+
+jQuery.fn.ready = function( fn ) {
+
+       readyList
+               .then( fn )
+
+               // Wrap jQuery.readyException in a function so that the lookup
+               // happens at the time of error handling instead of callback
+               // registration.
+               .catch( function( error ) {
+                       jQuery.readyException( error );
+               } );
+
+       return this;
+};
+
+jQuery.extend( {
+
+       // Is the DOM ready to be used? Set to true once it occurs.
+       isReady: false,
+
+       // A counter to track how many items to wait for before
+       // the ready event fires. See #6781
+       readyWait: 1,
+
+       // Handle when the DOM is ready
+       ready: function( wait ) {
+
+               // Abort if there are pending holds or we're already ready
+               if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) {
+                       return;
+               }
+
+               // Remember that the DOM is ready
+               jQuery.isReady = true;
+
+               // If a normal DOM Ready event fired, decrement, and wait if need be
+               if ( wait !== true && --jQuery.readyWait > 0 ) {
+                       return;
+               }
+
+               // If there are functions bound, to execute
+               readyList.resolveWith( document, [ jQuery ] );
+       }
+} );
+
+jQuery.ready.then = readyList.then;
+
+// The ready event handler and self cleanup method
+function completed() {
+       document.removeEventListener( "DOMContentLoaded", completed );
+       window.removeEventListener( "load", completed );
+       jQuery.ready();
+}
+
+// Catch cases where $(document).ready() is called
+// after the browser event has already occurred.
+// Support: IE <=9 - 10 only
+// Older IE sometimes signals "interactive" too soon
+if ( document.readyState === "complete" ||
+       ( document.readyState !== "loading" && !document.documentElement.doScroll ) ) {
+
+       // Handle it asynchronously to allow scripts the opportunity to delay ready
+       window.setTimeout( jQuery.ready );
+
+} else {
+
+       // Use the handy event callback
+       document.addEventListener( "DOMContentLoaded", completed );
+
+       // A fallback to window.onload, that will always work
+       window.addEventListener( "load", completed );
+}
+
+
+
+
+// Multifunctional method to get and set values of a collection
+// The value/s can optionally be executed if it's a function
+var access = function( elems, fn, key, value, chainable, emptyGet, raw ) {
+       var i = 0,
+               len = elems.length,
+               bulk = key == null;
+
+       // Sets many values
+       if ( jQuery.type( key ) === "object" ) {
+               chainable = true;
+               for ( i in key ) {
+                       access( elems, fn, i, key[ i ], true, emptyGet, raw );
+               }
+
+       // Sets one value
+       } else if ( value !== undefined ) {
+               chainable = true;
+
+               if ( !jQuery.isFunction( value ) ) {
+                       raw = true;
+               }
+
+               if ( bulk ) {
+
+                       // Bulk operations run against the entire set
+                       if ( raw ) {
+                               fn.call( elems, value );
+                               fn = null;
+
+                       // ...except when executing function values
+                       } else {
+                               bulk = fn;
+                               fn = function( elem, key, value ) {
+                                       return bulk.call( jQuery( elem ), value );
+                               };
+                       }
+               }
+
+               if ( fn ) {
+                       for ( ; i < len; i++ ) {
+                               fn(
+                                       elems[ i ], key, raw ?
+                                       value :
+                                       value.call( elems[ i ], i, fn( elems[ i ], key ) )
+                               );
+                       }
+               }
+       }
+
+       if ( chainable ) {
+               return elems;
+       }
+
+       // Gets
+       if ( bulk ) {
+               return fn.call( elems );
+       }
+
+       return len ? fn( elems[ 0 ], key ) : emptyGet;
+};
+var acceptData = function( owner ) {
+
+       // Accepts only:
+       //  - Node
+       //    - Node.ELEMENT_NODE
+       //    - Node.DOCUMENT_NODE
+       //  - Object
+       //    - Any
+       return owner.nodeType === 1 || owner.nodeType === 9 || !( +owner.nodeType );
+};
+
+
+
+
+function Data() {
+       this.expando = jQuery.expando + Data.uid++;
+}
+
+Data.uid = 1;
+
+Data.prototype = {
+
+       cache: function( owner ) {
+
+               // Check if the owner object already has a cache
+               var value = owner[ this.expando ];
+
+               // If not, create one
+               if ( !value ) {
+                       value = {};
+
+                       // We can accept data for non-element nodes in modern browsers,
+                       // but we should not, see #8335.
+                       // Always return an empty object.
+                       if ( acceptData( owner ) ) {
+
+                               // If it is a node unlikely to be stringify-ed or looped over
+                               // use plain assignment
+                               if ( owner.nodeType ) {
+                                       owner[ this.expando ] = value;
+
+                               // Otherwise secure it in a non-enumerable property
+                               // configurable must be true to allow the property to be
+                               // deleted when data is removed
+                               } else {
+                                       Object.defineProperty( owner, this.expando, {
+                                               value: value,
+                                               configurable: true
+                                       } );
+                               }
+                       }
+               }
+
+               return value;
+       },
+       set: function( owner, data, value ) {
+               var prop,
+                       cache = this.cache( owner );
+
+               // Handle: [ owner, key, value ] args
+               // Always use camelCase key (gh-2257)
+               if ( typeof data === "string" ) {
+                       cache[ jQuery.camelCase( data ) ] = value;
+
+               // Handle: [ owner, { properties } ] args
+               } else {
+
+                       // Copy the properties one-by-one to the cache object
+                       for ( prop in data ) {
+                               cache[ jQuery.camelCase( prop ) ] = data[ prop ];
+                       }
+               }
+               return cache;
+       },
+       get: function( owner, key ) {
+               return key === undefined ?
+                       this.cache( owner ) :
+
+                       // Always use camelCase key (gh-2257)
+                       owner[ this.expando ] && owner[ this.expando ][ jQuery.camelCase( key ) ];
+       },
+       access: function( owner, key, value ) {
+
+               // In cases where either:
+               //
+               //   1. No key was specified
+               //   2. A string key was specified, but no value provided
+               //
+               // Take the "read" path and allow the get method to determine
+               // which value to return, respectively either:
+               //
+               //   1. The entire cache object
+               //   2. The data stored at the key
+               //
+               if ( key === undefined ||
+                               ( ( key && typeof key === "string" ) && value === undefined ) ) {
+
+                       return this.get( owner, key );
+               }
+
+               // When the key is not a string, or both a key and value
+               // are specified, set or extend (existing objects) with either:
+               //
+               //   1. An object of properties
+               //   2. A key and value
+               //
+               this.set( owner, key, value );
+
+               // Since the "set" path can have two possible entry points
+               // return the expected data based on which path was taken[*]
+               return value !== undefined ? value : key;
+       },
+       remove: function( owner, key ) {
+               var i,
+                       cache = owner[ this.expando ];
+
+               if ( cache === undefined ) {
+                       return;
+               }
+
+               if ( key !== undefined ) {
+
+                       // Support array or space separated string of keys
+                       if ( Array.isArray( key ) ) {
+
+                               // If key is an array of keys...
+                               // We always set camelCase keys, so remove that.
+                               key = key.map( jQuery.camelCase );
+                       } else {
+                               key = jQuery.camelCase( key );
+
+                               // If a key with the spaces exists, use it.
+                               // Otherwise, create an array by matching non-whitespace
+                               key = key in cache ?
+                                       [ key ] :
+                                       ( key.match( rnothtmlwhite ) || [] );
+                       }
+
+                       i = key.length;
+
+                       while ( i-- ) {
+                               delete cache[ key[ i ] ];
+                       }
+               }
+
+               // Remove the expando if there's no more data
+               if ( key === undefined || jQuery.isEmptyObject( cache ) ) {
+
+                       // Support: Chrome <=35 - 45
+                       // Webkit & Blink performance suffers when deleting properties
+                       // from DOM nodes, so set to undefined instead
+                       // https://bugs.chromium.org/p/chromium/issues/detail?id=378607 (bug restricted)
+                       if ( owner.nodeType ) {
+                               owner[ this.expando ] = undefined;
+                       } else {
+                               delete owner[ this.expando ];
+                       }
+               }
+       },
+       hasData: function( owner ) {
+               var cache = owner[ this.expando ];
+               return cache !== undefined && !jQuery.isEmptyObject( cache );
+       }
+};
+var dataPriv = new Data();
+
+var dataUser = new Data();
+
+
+
+//     Implementation Summary
+//
+//     1. Enforce API surface and semantic compatibility with 1.9.x branch
+//     2. Improve the module's maintainability by reducing the storage
+//             paths to a single mechanism.
+//     3. Use the same single mechanism to support "private" and "user" data.
+//     4. _Never_ expose "private" data to user code (TODO: Drop _data, _removeData)
+//     5. Avoid exposing implementation details on user objects (eg. expando properties)
+//     6. Provide a clear path for implementation upgrade to WeakMap in 2014
+
+var rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,
+       rmultiDash = /[A-Z]/g;
+
+function getData( data ) {
+       if ( data === "true" ) {
+               return true;
+       }
+
+       if ( data === "false" ) {
+               return false;
+       }
+
+       if ( data === "null" ) {
+               return null;
+       }
+
+       // Only convert to a number if it doesn't change the string
+       if ( data === +data + "" ) {
+               return +data;
+       }
+
+       if ( rbrace.test( data ) ) {
+               return JSON.parse( data );
+       }
+
+       return data;
+}
+
+function dataAttr( elem, key, data ) {
+       var name;
+
+       // If nothing was found internally, try to fetch any
+       // data from the HTML5 data-* attribute
+       if ( data === undefined && elem.nodeType === 1 ) {
+               name = "data-" + key.replace( rmultiDash, "-$&" ).toLowerCase();
+               data = elem.getAttribute( name );
+
+               if ( typeof data === "string" ) {
+                       try {
+                               data = getData( data );
+                       } catch ( e ) {}
+
+                       // Make sure we set the data so it isn't changed later
+                       dataUser.set( elem, key, data );
+               } else {
+                       data = undefined;
+               }
+       }
+       return data;
+}
+
+jQuery.extend( {
+       hasData: function( elem ) {
+               return dataUser.hasData( elem ) || dataPriv.hasData( elem );
+       },
+
+       data: function( elem, name, data ) {
+               return dataUser.access( elem, name, data );
+       },
+
+       removeData: function( elem, name ) {
+               dataUser.remove( elem, name );
+       },
+
+       // TODO: Now that all calls to _data and _removeData have been replaced
+       // with direct calls to dataPriv methods, these can be deprecated.
+       _data: function( elem, name, data ) {
+               return dataPriv.access( elem, name, data );
+       },
+
+       _removeData: function( elem, name ) {
+               dataPriv.remove( elem, name );
+       }
+} );
+
+jQuery.fn.extend( {
+       data: function( key, value ) {
+               var i, name, data,
+                       elem = this[ 0 ],
+                       attrs = elem && elem.attributes;
+
+               // Gets all values
+               if ( key === undefined ) {
+                       if ( this.length ) {
+                               data = dataUser.get( elem );
+
+                               if ( elem.nodeType === 1 && !dataPriv.get( elem, "hasDataAttrs" ) ) {
+                                       i = attrs.length;
+                                       while ( i-- ) {
+
+                                               // Support: IE 11 only
+                                               // The attrs elements can be null (#14894)
+                                               if ( attrs[ i ] ) {
+                                                       name = attrs[ i ].name;
+                                                       if ( name.indexOf( "data-" ) === 0 ) {
+                                                               name = jQuery.camelCase( name.slice( 5 ) );
+                                                               dataAttr( elem, name, data[ name ] );
+                                                       }
+                                               }
+                                       }
+                                       dataPriv.set( elem, "hasDataAttrs", true );
+                               }
+                       }
+
+                       return data;
+               }
+
+               // Sets multiple values
+               if ( typeof key === "object" ) {
+                       return this.each( function() {
+                               dataUser.set( this, key );
+                       } );
+               }
+
+               return access( this, function( value ) {
+                       var data;
+
+                       // The calling jQuery object (element matches) is not empty
+                       // (and therefore has an element appears at this[ 0 ]) and the
+                       // `value` parameter was not undefined. An empty jQuery object
+                       // will result in `undefined` for elem = this[ 0 ] which will
+                       // throw an exception if an attempt to read a data cache is made.
+                       if ( elem && value === undefined ) {
+
+                               // Attempt to get data from the cache
+                               // The key will always be camelCased in Data
+                               data = dataUser.get( elem, key );
+                               if ( data !== undefined ) {
+                                       return data;
+                               }
+
+                               // Attempt to "discover" the data in
+                               // HTML5 custom data-* attrs
+                               data = dataAttr( elem, key );
+                               if ( data !== undefined ) {
+                                       return data;
+                               }
+
+                               // We tried really hard, but the data doesn't exist.
+                               return;
+                       }
+
+                       // Set the data...
+                       this.each( function() {
+
+                               // We always store the camelCased key
+                               dataUser.set( this, key, value );
+                       } );
+               }, null, value, arguments.length > 1, null, true );
+       },
+
+       removeData: function( key ) {
+               return this.each( function() {
+                       dataUser.remove( this, key );
+               } );
+       }
+} );
+
+
+jQuery.extend( {
+       queue: function( elem, type, data ) {
+               var queue;
+
+               if ( elem ) {
+                       type = ( type || "fx" ) + "queue";
+                       queue = dataPriv.get( elem, type );
+
+                       // Speed up dequeue by getting out quickly if this is just a lookup
+                       if ( data ) {
+                               if ( !queue || Array.isArray( data ) ) {
+                                       queue = dataPriv.access( elem, type, jQuery.makeArray( data ) );
+                               } else {
+                                       queue.push( data );
+                               }
+                       }
+                       return queue || [];
+               }
+       },
+
+       dequeue: function( elem, type ) {
+               type = type || "fx";
+
+               var queue = jQuery.queue( elem, type ),
+                       startLength = queue.length,
+                       fn = queue.shift(),
+                       hooks = jQuery._queueHooks( elem, type ),
+                       next = function() {
+                               jQuery.dequeue( elem, type );
+                       };
+
+               // If the fx queue is dequeued, always remove the progress sentinel
+               if ( fn === "inprogress" ) {
+                       fn = queue.shift();
+                       startLength--;
+               }
+
+               if ( fn ) {
+
+                       // Add a progress sentinel to prevent the fx queue from being
+                       // automatically dequeued
+                       if ( type === "fx" ) {
+                               queue.unshift( "inprogress" );
+                       }
+
+                       // Clear up the last queue stop function
+                       delete hooks.stop;
+                       fn.call( elem, next, hooks );
+               }
+
+               if ( !startLength && hooks ) {
+                       hooks.empty.fire();
+               }
+       },
+
+       // Not public - generate a queueHooks object, or return the current one
+       _queueHooks: function( elem, type ) {
+               var key = type + "queueHooks";
+               return dataPriv.get( elem, key ) || dataPriv.access( elem, key, {
+                       empty: jQuery.Callbacks( "once memory" ).add( function() {
+                               dataPriv.remove( elem, [ type + "queue", key ] );
+                       } )
+               } );
+       }
+} );
+
+jQuery.fn.extend( {
+       queue: function( type, data ) {
+               var setter = 2;
+
+               if ( typeof type !== "string" ) {
+                       data = type;
+                       type = "fx";
+                       setter--;
+               }
+
+               if ( arguments.length < setter ) {
+                       return jQuery.queue( this[ 0 ], type );
+               }
+
+               return data === undefined ?
+                       this :
+                       this.each( function() {
+                               var queue = jQuery.queue( this, type, data );
+
+                               // Ensure a hooks for this queue
+                               jQuery._queueHooks( this, type );
+
+                               if ( type === "fx" && queue[ 0 ] !== "inprogress" ) {
+                                       jQuery.dequeue( this, type );
+                               }
+                       } );
+       },
+       dequeue: function( type ) {
+               return this.each( function() {
+                       jQuery.dequeue( this, type );
+               } );
+       },
+       clearQueue: function( type ) {
+               return this.queue( type || "fx", [] );
+       },
+
+       // Get a promise resolved when queues of a certain type
+       // are emptied (fx is the type by default)
+       promise: function( type, obj ) {
+               var tmp,
+                       count = 1,
+                       defer = jQuery.Deferred(),
+                       elements = this,
+                       i = this.length,
+                       resolve = function() {
+                               if ( !( --count ) ) {
+                                       defer.resolveWith( elements, [ elements ] );
+                               }
+                       };
+
+               if ( typeof type !== "string" ) {
+                       obj = type;
+                       type = undefined;
+               }
+               type = type || "fx";
+
+               while ( i-- ) {
+                       tmp = dataPriv.get( elements[ i ], type + "queueHooks" );
+                       if ( tmp && tmp.empty ) {
+                               count++;
+                               tmp.empty.add( resolve );
+                       }
+               }
+               resolve();
+               return defer.promise( obj );
+       }
+} );
+var pnum = ( /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/ ).source;
+
+var rcssNum = new RegExp( "^(?:([+-])=|)(" + pnum + ")([a-z%]*)$", "i" );
+
+
+var cssExpand = [ "Top", "Right", "Bottom", "Left" ];
+
+var isHiddenWithinTree = function( elem, el ) {
+
+               // isHiddenWithinTree might be called from jQuery#filter function;
+               // in that case, element will be second argument
+               elem = el || elem;
+
+               // Inline style trumps all
+               return elem.style.display === "none" ||
+                       elem.style.display === "" &&
+
+                       // Otherwise, check computed style
+                       // Support: Firefox <=43 - 45
+                       // Disconnected elements can have computed display: none, so first confirm that elem 
is
+                       // in the document.
+                       jQuery.contains( elem.ownerDocument, elem ) &&
+
+                       jQuery.css( elem, "display" ) === "none";
+       };
+
+var swap = function( elem, options, callback, args ) {
+       var ret, name,
+               old = {};
+
+       // Remember the old values, and insert the new ones
+       for ( name in options ) {
+               old[ name ] = elem.style[ name ];
+               elem.style[ name ] = options[ name ];
+       }
+
+       ret = callback.apply( elem, args || [] );
+
+       // Revert the old values
+       for ( name in options ) {
+               elem.style[ name ] = old[ name ];
+       }
+
+       return ret;
+};
+
+
+
+
+function adjustCSS( elem, prop, valueParts, tween ) {
+       var adjusted,
+               scale = 1,
+               maxIterations = 20,
+               currentValue = tween ?
+                       function() {
+                               return tween.cur();
+                       } :
+                       function() {
+                               return jQuery.css( elem, prop, "" );
+                       },
+               initial = currentValue(),
+               unit = valueParts && valueParts[ 3 ] || ( jQuery.cssNumber[ prop ] ? "" : "px" ),
+
+               // Starting value computation is required for potential unit mismatches
+               initialInUnit = ( jQuery.cssNumber[ prop ] || unit !== "px" && +initial ) &&
+                       rcssNum.exec( jQuery.css( elem, prop ) );
+
+       if ( initialInUnit && initialInUnit[ 3 ] !== unit ) {
+
+               // Trust units reported by jQuery.css
+               unit = unit || initialInUnit[ 3 ];
+
+               // Make sure we update the tween properties later on
+               valueParts = valueParts || [];
+
+               // Iteratively approximate from a nonzero starting point
+               initialInUnit = +initial || 1;
+
+               do {
+
+                       // If previous iteration zeroed out, double until we get *something*.
+                       // Use string for doubling so we don't accidentally see scale as unchanged below
+                       scale = scale || ".5";
+
+                       // Adjust and apply
+                       initialInUnit = initialInUnit / scale;
+                       jQuery.style( elem, prop, initialInUnit + unit );
+
+               // Update scale, tolerating zero or NaN from tween.cur()
+               // Break the loop if scale is unchanged or perfect, or if we've just had enough.
+               } while (
+                       scale !== ( scale = currentValue() / initial ) && scale !== 1 && --maxIterations
+               );
+       }
+
+       if ( valueParts ) {
+               initialInUnit = +initialInUnit || +initial || 0;
+
+               // Apply relative offset (+=/-=) if specified
+               adjusted = valueParts[ 1 ] ?
+                       initialInUnit + ( valueParts[ 1 ] + 1 ) * valueParts[ 2 ] :
+                       +valueParts[ 2 ];
+               if ( tween ) {
+                       tween.unit = unit;
+                       tween.start = initialInUnit;
+                       tween.end = adjusted;
+               }
+       }
+       return adjusted;
+}
+
+
+var defaultDisplayMap = {};
+
+function getDefaultDisplay( elem ) {
+       var temp,
+               doc = elem.ownerDocument,
+               nodeName = elem.nodeName,
+               display = defaultDisplayMap[ nodeName ];
+
+       if ( display ) {
+               return display;
+       }
+
+       temp = doc.body.appendChild( doc.createElement( nodeName ) );
+       display = jQuery.css( temp, "display" );
+
+       temp.parentNode.removeChild( temp );
+
+       if ( display === "none" ) {
+               display = "block";
+       }
+       defaultDisplayMap[ nodeName ] = display;
+
+       return display;
+}
+
+function showHide( elements, show ) {
+       var display, elem,
+               values = [],
+               index = 0,
+               length = elements.length;
+
+       // Determine new display value for elements that need to change
+       for ( ; index < length; index++ ) {
+               elem = elements[ index ];
+               if ( !elem.style ) {
+                       continue;
+               }
+
+               display = elem.style.display;
+               if ( show ) {
+
+                       // Since we force visibility upon cascade-hidden elements, an immediate (and slow)
+                       // check is required in this first loop unless we have a nonempty display value 
(either
+                       // inline or about-to-be-restored)
+                       if ( display === "none" ) {
+                               values[ index ] = dataPriv.get( elem, "display" ) || null;
+                               if ( !values[ index ] ) {
+                                       elem.style.display = "";
+                               }
+                       }
+                       if ( elem.style.display === "" && isHiddenWithinTree( elem ) ) {
+                               values[ index ] = getDefaultDisplay( elem );
+                       }
+               } else {
+                       if ( display !== "none" ) {
+                               values[ index ] = "none";
+
+                               // Remember what we're overwriting
+                               dataPriv.set( elem, "display", display );
+                       }
+               }
+       }
+
+       // Set the display of the elements in a second loop to avoid constant reflow
+       for ( index = 0; index < length; index++ ) {
+               if ( values[ index ] != null ) {
+                       elements[ index ].style.display = values[ index ];
+               }
+       }
+
+       return elements;
+}
+
+jQuery.fn.extend( {
+       show: function() {
+               return showHide( this, true );
+       },
+       hide: function() {
+               return showHide( this );
+       },
+       toggle: function( state ) {
+               if ( typeof state === "boolean" ) {
+                       return state ? this.show() : this.hide();
+               }
+
+               return this.each( function() {
+                       if ( isHiddenWithinTree( this ) ) {
+                               jQuery( this ).show();
+                       } else {
+                               jQuery( this ).hide();
+                       }
+               } );
+       }
+} );
+var rcheckableType = ( /^(?:checkbox|radio)$/i );
+
+var rtagName = ( /<([a-z][^\/\0>\x20\t\r\n\f]+)/i );
+
+var rscriptType = ( /^$|\/(?:java|ecma)script/i );
+
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+
+       // Support: IE <=9 only
+       option: [ 1, "<select multiple='multiple'>", "</select>" ],
+
+       // XHTML parsers do not magically insert elements in the
+       // same way that tag soup parsers do. So we cannot shorten
+       // this by omitting <tbody> or other required elements.
+       thead: [ 1, "<table>", "</table>" ],
+       col: [ 2, "<table><colgroup>", "</colgroup></table>" ],
+       tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+       td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+       _default: [ 0, "", "" ]
+};
+
+// Support: IE <=9 only
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+
+       // Support: IE <=9 - 11 only
+       // Use typeof to avoid zero-argument method invocation on host objects (#15151)
+       var ret;
+
+       if ( typeof context.getElementsByTagName !== "undefined" ) {
+               ret = context.getElementsByTagName( tag || "*" );
+
+       } else if ( typeof context.querySelectorAll !== "undefined" ) {
+               ret = context.querySelectorAll( tag || "*" );
+
+       } else {
+               ret = [];
+       }
+
+       if ( tag === undefined || tag && nodeName( context, tag ) ) {
+               return jQuery.merge( [ context ], ret );
+       }
+
+       return ret;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+       var i = 0,
+               l = elems.length;
+
+       for ( ; i < l; i++ ) {
+               dataPriv.set(
+                       elems[ i ],
+                       "globalEval",
+                       !refElements || dataPriv.get( refElements[ i ], "globalEval" )
+               );
+       }
+}
+
+
+var rhtml = /<|&#?\w+;/;
+
+function buildFragment( elems, context, scripts, selection, ignored ) {
+       var elem, tmp, tag, wrap, contains, j,
+               fragment = context.createDocumentFragment(),
+               nodes = [],
+               i = 0,
+               l = elems.length;
+
+       for ( ; i < l; i++ ) {
+               elem = elems[ i ];
+
+               if ( elem || elem === 0 ) {
+
+                       // Add nodes directly
+                       if ( jQuery.type( elem ) === "object" ) {
+
+                               // Support: Android <=4.0 only, PhantomJS 1 only
+                               // push.apply(_, arraylike) throws on ancient WebKit
+                               jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+                       // Convert non-html into a text node
+                       } else if ( !rhtml.test( elem ) ) {
+                               nodes.push( context.createTextNode( elem ) );
+
+                       // Convert html into DOM nodes
+                       } else {
+                               tmp = tmp || fragment.appendChild( context.createElement( "div" ) );
+
+                               // Deserialize a standard representation
+                               tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+                               wrap = wrapMap[ tag ] || wrapMap._default;
+                               tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+                               // Descend through wrappers to the right content
+                               j = wrap[ 0 ];
+                               while ( j-- ) {
+                                       tmp = tmp.lastChild;
+                               }
+
+                               // Support: Android <=4.0 only, PhantomJS 1 only
+                               // push.apply(_, arraylike) throws on ancient WebKit
+                               jQuery.merge( nodes, tmp.childNodes );
+
+                               // Remember the top-level container
+                               tmp = fragment.firstChild;
+
+                               // Ensure the created nodes are orphaned (#12392)
+                               tmp.textContent = "";
+                       }
+               }
+       }
+
+       // Remove wrapper from fragment
+       fragment.textContent = "";
+
+       i = 0;
+       while ( ( elem = nodes[ i++ ] ) ) {
+
+               // Skip elements already in the context collection (trac-4087)
+               if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+                       if ( ignored ) {
+                               ignored.push( elem );
+                       }
+                       continue;
+               }
+
+               contains = jQuery.contains( elem.ownerDocument, elem );
+
+               // Append to fragment
+               tmp = getAll( fragment.appendChild( elem ), "script" );
+
+               // Preserve script evaluation history
+               if ( contains ) {
+                       setGlobalEval( tmp );
+               }
+
+               // Capture executables
+               if ( scripts ) {
+                       j = 0;
+                       while ( ( elem = tmp[ j++ ] ) ) {
+                               if ( rscriptType.test( elem.type || "" ) ) {
+                                       scripts.push( elem );
+                               }
+                       }
+               }
+       }
+
+       return fragment;
+}
+
+
+( function() {
+       var fragment = document.createDocumentFragment(),
+               div = fragment.appendChild( document.createElement( "div" ) ),
+               input = document.createElement( "input" );
+
+       // Support: Android 4.0 - 4.3 only
+       // Check state lost if the name is set (#11217)
+       // Support: Windows Web Apps (WWA)
+       // `name` and `type` must use .setAttribute for WWA (#14901)
+       input.setAttribute( "type", "radio" );
+       input.setAttribute( "checked", "checked" );
+       input.setAttribute( "name", "t" );
+
+       div.appendChild( input );
+
+       // Support: Android <=4.1 only
+       // Older WebKit doesn't clone checked state correctly in fragments
+       support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+       // Support: IE <=11 only
+       // Make sure textarea (and checkbox) defaultValue is properly cloned
+       div.innerHTML = "<textarea>x</textarea>";
+       support.noCloneChecked = !!div.cloneNode( true ).lastChild.defaultValue;
+} )();
+var documentElement = document.documentElement;
+
+
+
+var
+       rkeyEvent = /^key/,
+       rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
+       rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
+
+function returnTrue() {
+       return true;
+}
+
+function returnFalse() {
+       return false;
+}
+
+// Support: IE <=9 only
+// See #13393 for more info
+function safeActiveElement() {
+       try {
+               return document.activeElement;
+       } catch ( err ) { }
+}
+
+function on( elem, types, selector, data, fn, one ) {
+       var origFn, type;
+
+       // Types can be a map of types/handlers
+       if ( typeof types === "object" ) {
+
+               // ( types-Object, selector, data )
+               if ( typeof selector !== "string" ) {
+
+                       // ( types-Object, data )
+                       data = data || selector;
+                       selector = undefined;
+               }
+               for ( type in types ) {
+                       on( elem, type, selector, data, types[ type ], one );
+               }
+               return elem;
+       }
+
+       if ( data == null && fn == null ) {
+
+               // ( types, fn )
+               fn = selector;
+               data = selector = undefined;
+       } else if ( fn == null ) {
+               if ( typeof selector === "string" ) {
+
+                       // ( types, selector, fn )
+                       fn = data;
+                       data = undefined;
+               } else {
+
+                       // ( types, data, fn )
+                       fn = data;
+                       data = selector;
+                       selector = undefined;
+               }
+       }
+       if ( fn === false ) {
+               fn = returnFalse;
+       } else if ( !fn ) {
+               return elem;
+       }
+
+       if ( one === 1 ) {
+               origFn = fn;
+               fn = function( event ) {
+
+                       // Can use an empty set, since event contains the info
+                       jQuery().off( event );
+                       return origFn.apply( this, arguments );
+               };
+
+               // Use same guid so caller can remove using origFn
+               fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+       }
+       return elem.each( function() {
+               jQuery.event.add( this, types, fn, data, selector );
+       } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+       global: {},
+
+       add: function( elem, types, handler, data, selector ) {
+
+               var handleObjIn, eventHandle, tmp,
+                       events, t, handleObj,
+                       special, handlers, type, namespaces, origType,
+                       elemData = dataPriv.get( elem );
+
+               // Don't attach events to noData or text/comment nodes (but allow plain objects)
+               if ( !elemData ) {
+                       return;
+               }
+
+               // Caller can pass in an object of custom data in lieu of the handler
+               if ( handler.handler ) {
+                       handleObjIn = handler;
+                       handler = handleObjIn.handler;
+                       selector = handleObjIn.selector;
+               }
+
+               // Ensure that invalid selectors throw exceptions at attach time
+               // Evaluate against documentElement in case elem is a non-element node (e.g., document)
+               if ( selector ) {
+                       jQuery.find.matchesSelector( documentElement, selector );
+               }
+
+               // Make sure that the handler has a unique ID, used to find/remove it later
+               if ( !handler.guid ) {
+                       handler.guid = jQuery.guid++;
+               }
+
+               // Init the element's event structure and main handler, if this is the first
+               if ( !( events = elemData.events ) ) {
+                       events = elemData.events = {};
+               }
+               if ( !( eventHandle = elemData.handle ) ) {
+                       eventHandle = elemData.handle = function( e ) {
+
+                               // Discard the second event of a jQuery.event.trigger() and
+                               // when an event is called after a page has unloaded
+                               return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
+                                       jQuery.event.dispatch.apply( elem, arguments ) : undefined;
+                       };
+               }
+
+               // Handle multiple events separated by a space
+               types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[ t ] ) || [];
+                       type = origType = tmp[ 1 ];
+                       namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+                       // There *must* be a type, no attaching namespace-only handlers
+                       if ( !type ) {
+                               continue;
+                       }
+
+                       // If event changes its type, use the special event handlers for the changed type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // If selector defined, determine special event api type, otherwise given type
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+
+                       // Update special based on newly reset type
+                       special = jQuery.event.special[ type ] || {};
+
+                       // handleObj is passed to all event handlers
+                       handleObj = jQuery.extend( {
+                               type: type,
+                               origType: origType,
+                               data: data,
+                               handler: handler,
+                               guid: handler.guid,
+                               selector: selector,
+                               needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
+                               namespace: namespaces.join( "." )
+                       }, handleObjIn );
+
+                       // Init the event handler queue if we're the first
+                       if ( !( handlers = events[ type ] ) ) {
+                               handlers = events[ type ] = [];
+                               handlers.delegateCount = 0;
+
+                               // Only use addEventListener if the special events handler returns false
+                               if ( !special.setup ||
+                                       special.setup.call( elem, data, namespaces, eventHandle ) === false ) 
{
+
+                                       if ( elem.addEventListener ) {
+                                               elem.addEventListener( type, eventHandle );
+                                       }
+                               }
+                       }
+
+                       if ( special.add ) {
+                               special.add.call( elem, handleObj );
+
+                               if ( !handleObj.handler.guid ) {
+                                       handleObj.handler.guid = handler.guid;
+                               }
+                       }
+
+                       // Add to the element's handler list, delegates in front
+                       if ( selector ) {
+                               handlers.splice( handlers.delegateCount++, 0, handleObj );
+                       } else {
+                               handlers.push( handleObj );
+                       }
+
+                       // Keep track of which events have ever been used, for event optimization
+                       jQuery.event.global[ type ] = true;
+               }
+
+       },
+
+       // Detach an event or set of events from an element
+       remove: function( elem, types, handler, selector, mappedTypes ) {
+
+               var j, origCount, tmp,
+                       events, t, handleObj,
+                       special, handlers, type, namespaces, origType,
+                       elemData = dataPriv.hasData( elem ) && dataPriv.get( elem );
+
+               if ( !elemData || !( events = elemData.events ) ) {
+                       return;
+               }
+
+               // Once for each type.namespace in types; type may be omitted
+               types = ( types || "" ).match( rnothtmlwhite ) || [ "" ];
+               t = types.length;
+               while ( t-- ) {
+                       tmp = rtypenamespace.exec( types[ t ] ) || [];
+                       type = origType = tmp[ 1 ];
+                       namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
+
+                       // Unbind all events (on this namespace, if provided) for the element
+                       if ( !type ) {
+                               for ( type in events ) {
+                                       jQuery.event.remove( elem, type + types[ t ], handler, selector, true 
);
+                               }
+                               continue;
+                       }
+
+                       special = jQuery.event.special[ type ] || {};
+                       type = ( selector ? special.delegateType : special.bindType ) || type;
+                       handlers = events[ type ] || [];
+                       tmp = tmp[ 2 ] &&
+                               new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
+
+                       // Remove matching events
+                       origCount = j = handlers.length;
+                       while ( j-- ) {
+                               handleObj = handlers[ j ];
+
+                               if ( ( mappedTypes || origType === handleObj.origType ) &&
+                                       ( !handler || handler.guid === handleObj.guid ) &&
+                                       ( !tmp || tmp.test( handleObj.namespace ) ) &&
+                                       ( !selector || selector === handleObj.selector ||
+                                               selector === "**" && handleObj.selector ) ) {
+                                       handlers.splice( j, 1 );
+
+                                       if ( handleObj.selector ) {
+                                               handlers.delegateCount--;
+                                       }
+                                       if ( special.remove ) {
+                                               special.remove.call( elem, handleObj );
+                                       }
+                               }
+                       }
+
+                       // Remove generic event handler if we removed something and no more handlers exist
+                       // (avoids potential for endless recursion during removal of special event handlers)
+                       if ( origCount && !handlers.length ) {
+                               if ( !special.teardown ||
+                                       special.teardown.call( elem, namespaces, elemData.handle ) === false 
) {
+
+                                       jQuery.removeEvent( elem, type, elemData.handle );
+                               }
+
+                               delete events[ type ];
+                       }
+               }
+
+               // Remove data and the expando if it's no longer used
+               if ( jQuery.isEmptyObject( events ) ) {
+                       dataPriv.remove( elem, "handle events" );
+               }
+       },
+
+       dispatch: function( nativeEvent ) {
+
+               // Make a writable jQuery.Event from the native event object
+               var event = jQuery.event.fix( nativeEvent );
+
+               var i, j, ret, matched, handleObj, handlerQueue,
+                       args = new Array( arguments.length ),
+                       handlers = ( dataPriv.get( this, "events" ) || {} )[ event.type ] || [],
+                       special = jQuery.event.special[ event.type ] || {};
+
+               // Use the fix-ed jQuery.Event rather than the (read-only) native event
+               args[ 0 ] = event;
+
+               for ( i = 1; i < arguments.length; i++ ) {
+                       args[ i ] = arguments[ i ];
+               }
+
+               event.delegateTarget = this;
+
+               // Call the preDispatch hook for the mapped type, and let it bail if desired
+               if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) {
+                       return;
+               }
+
+               // Determine handlers
+               handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+               // Run delegates first; they may want to stop propagation beneath us
+               i = 0;
+               while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
+                       event.currentTarget = matched.elem;
+
+                       j = 0;
+                       while ( ( handleObj = matched.handlers[ j++ ] ) &&
+                               !event.isImmediatePropagationStopped() ) {
+
+                               // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+                               // a subset or equal to those in the bound event (both can have no namespace).
+                               if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
+
+                                       event.handleObj = handleObj;
+                                       event.data = handleObj.data;
+
+                                       ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+                                               handleObj.handler ).apply( matched.elem, args );
+
+                                       if ( ret !== undefined ) {
+                                               if ( ( event.result = ret ) === false ) {
+                                                       event.preventDefault();
+                                                       event.stopPropagation();
+                                               }
+                                       }
+                               }
+                       }
+               }
+
+               // Call the postDispatch hook for the mapped type
+               if ( special.postDispatch ) {
+                       special.postDispatch.call( this, event );
+               }
+
+               return event.result;
+       },
+
+       handlers: function( event, handlers ) {
+               var i, handleObj, sel, matchedHandlers, matchedSelectors,
+                       handlerQueue = [],
+                       delegateCount = handlers.delegateCount,
+                       cur = event.target;
+
+               // Find delegate handlers
+               if ( delegateCount &&
+
+                       // Support: IE <=9
+                       // Black-hole SVG <use> instance trees (trac-13180)
+                       cur.nodeType &&
+
+                       // Support: Firefox <=42
+                       // Suppress spec-violating clicks indicating a non-primary pointer button (trac-3861)
+                       // https://www.w3.org/TR/DOM-Level-3-Events/#event-type-click
+                       // Support: IE 11 only
+                       // ...but not arrow key "clicks" of radio inputs, which can have `button` -1 (gh-2343)
+                       !( event.type === "click" && event.button >= 1 ) ) {
+
+                       for ( ; cur !== this; cur = cur.parentNode || this ) {
+
+                               // Don't check non-elements (#13208)
+                               // Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+                               if ( cur.nodeType === 1 && !( event.type === "click" && cur.disabled === true 
) ) {
+                                       matchedHandlers = [];
+                                       matchedSelectors = {};
+                                       for ( i = 0; i < delegateCount; i++ ) {
+                                               handleObj = handlers[ i ];
+
+                                               // Don't conflict with Object.prototype properties (#13203)
+                                               sel = handleObj.selector + " ";
+
+                                               if ( matchedSelectors[ sel ] === undefined ) {
+                                                       matchedSelectors[ sel ] = handleObj.needsContext ?
+                                                               jQuery( sel, this ).index( cur ) > -1 :
+                                                               jQuery.find( sel, this, null, [ cur ] 
).length;
+                                               }
+                                               if ( matchedSelectors[ sel ] ) {
+                                                       matchedHandlers.push( handleObj );
+                                               }
+                                       }
+                                       if ( matchedHandlers.length ) {
+                                               handlerQueue.push( { elem: cur, handlers: matchedHandlers } );
+                                       }
+                               }
+                       }
+               }
+
+               // Add the remaining (directly-bound) handlers
+               cur = this;
+               if ( delegateCount < handlers.length ) {
+                       handlerQueue.push( { elem: cur, handlers: handlers.slice( delegateCount ) } );
+               }
+
+               return handlerQueue;
+       },
+
+       addProp: function( name, hook ) {
+               Object.defineProperty( jQuery.Event.prototype, name, {
+                       enumerable: true,
+                       configurable: true,
+
+                       get: jQuery.isFunction( hook ) ?
+                               function() {
+                                       if ( this.originalEvent ) {
+                                                       return hook( this.originalEvent );
+                                       }
+                               } :
+                               function() {
+                                       if ( this.originalEvent ) {
+                                                       return this.originalEvent[ name ];
+                                       }
+                               },
+
+                       set: function( value ) {
+                               Object.defineProperty( this, name, {
+                                       enumerable: true,
+                                       configurable: true,
+                                       writable: true,
+                                       value: value
+                               } );
+                       }
+               } );
+       },
+
+       fix: function( originalEvent ) {
+               return originalEvent[ jQuery.expando ] ?
+                       originalEvent :
+                       new jQuery.Event( originalEvent );
+       },
+
+       special: {
+               load: {
+
+                       // Prevent triggered image.load events from bubbling to window.load
+                       noBubble: true
+               },
+               focus: {
+
+                       // Fire native event if possible so blur/focus sequence is correct
+                       trigger: function() {
+                               if ( this !== safeActiveElement() && this.focus ) {
+                                       this.focus();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusin"
+               },
+               blur: {
+                       trigger: function() {
+                               if ( this === safeActiveElement() && this.blur ) {
+                                       this.blur();
+                                       return false;
+                               }
+                       },
+                       delegateType: "focusout"
+               },
+               click: {
+
+                       // For checkbox, fire native event so checked state will be right
+                       trigger: function() {
+                               if ( this.type === "checkbox" && this.click && nodeName( this, "input" ) ) {
+                                       this.click();
+                                       return false;
+                               }
+                       },
+
+                       // For cross-browser consistency, don't fire native .click() on links
+                       _default: function( event ) {
+                               return nodeName( event.target, "a" );
+                       }
+               },
+
+               beforeunload: {
+                       postDispatch: function( event ) {
+
+                               // Support: Firefox 20+
+                               // Firefox doesn't alert if the returnValue field is not set.
+                               if ( event.result !== undefined && event.originalEvent ) {
+                                       event.originalEvent.returnValue = event.result;
+                               }
+                       }
+               }
+       }
+};
+
+jQuery.removeEvent = function( elem, type, handle ) {
+
+       // This "if" is needed for plain objects
+       if ( elem.removeEventListener ) {
+               elem.removeEventListener( type, handle );
+       }
+};
+
+jQuery.Event = function( src, props ) {
+
+       // Allow instantiation without the 'new' keyword
+       if ( !( this instanceof jQuery.Event ) ) {
+               return new jQuery.Event( src, props );
+       }
+
+       // Event object
+       if ( src && src.type ) {
+               this.originalEvent = src;
+               this.type = src.type;
+
+               // Events bubbling up the document may have been marked as prevented
+               // by a handler lower down the tree; reflect the correct value.
+               this.isDefaultPrevented = src.defaultPrevented ||
+                               src.defaultPrevented === undefined &&
+
+                               // Support: Android <=2.3 only
+                               src.returnValue === false ?
+                       returnTrue :
+                       returnFalse;
+
+               // Create target properties
+               // Support: Safari <=6 - 7 only
+               // Target should not be a text node (#504, #13143)
+               this.target = ( src.target && src.target.nodeType === 3 ) ?
+                       src.target.parentNode :
+                       src.target;
+
+               this.currentTarget = src.currentTarget;
+               this.relatedTarget = src.relatedTarget;
+
+       // Event type
+       } else {
+               this.type = src;
+       }
+
+       // Put explicitly provided properties onto the event object
+       if ( props ) {
+               jQuery.extend( this, props );
+       }
+
+       // Create a timestamp if incoming event doesn't have one
+       this.timeStamp = src && src.timeStamp || jQuery.now();
+
+       // Mark it as fixed
+       this[ jQuery.expando ] = true;
+};
+
+// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding
+// https://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html
+jQuery.Event.prototype = {
+       constructor: jQuery.Event,
+       isDefaultPrevented: returnFalse,
+       isPropagationStopped: returnFalse,
+       isImmediatePropagationStopped: returnFalse,
+       isSimulated: false,
+
+       preventDefault: function() {
+               var e = this.originalEvent;
+
+               this.isDefaultPrevented = returnTrue;
+
+               if ( e && !this.isSimulated ) {
+                       e.preventDefault();
+               }
+       },
+       stopPropagation: function() {
+               var e = this.originalEvent;
+
+               this.isPropagationStopped = returnTrue;
+
+               if ( e && !this.isSimulated ) {
+                       e.stopPropagation();
+               }
+       },
+       stopImmediatePropagation: function() {
+               var e = this.originalEvent;
+
+               this.isImmediatePropagationStopped = returnTrue;
+
+               if ( e && !this.isSimulated ) {
+                       e.stopImmediatePropagation();
+               }
+
+               this.stopPropagation();
+       }
+};
+
+// Includes all common event props including KeyEvent and MouseEvent specific props
+jQuery.each( {
+       altKey: true,
+       bubbles: true,
+       cancelable: true,
+       changedTouches: true,
+       ctrlKey: true,
+       detail: true,
+       eventPhase: true,
+       metaKey: true,
+       pageX: true,
+       pageY: true,
+       shiftKey: true,
+       view: true,
+       "char": true,
+       charCode: true,
+       key: true,
+       keyCode: true,
+       button: true,
+       buttons: true,
+       clientX: true,
+       clientY: true,
+       offsetX: true,
+       offsetY: true,
+       pointerId: true,
+       pointerType: true,
+       screenX: true,
+       screenY: true,
+       targetTouches: true,
+       toElement: true,
+       touches: true,
+
+       which: function( event ) {
+               var button = event.button;
+
+               // Add which for key events
+               if ( event.which == null && rkeyEvent.test( event.type ) ) {
+                       return event.charCode != null ? event.charCode : event.keyCode;
+               }
+
+               // Add which for click: 1 === left; 2 === middle; 3 === right
+               if ( !event.which && button !== undefined && rmouseEvent.test( event.type ) ) {
+                       if ( button & 1 ) {
+                               return 1;
+                       }
+
+                       if ( button & 2 ) {
+                               return 3;
+                       }
+
+                       if ( button & 4 ) {
+                               return 2;
+                       }
+
+                       return 0;
+               }
+
+               return event.which;
+       }
+}, jQuery.event.addProp );
+
+// Create mouseenter/leave events using mouseover/out and event-time checks
+// so that event delegation works in jQuery.
+// Do the same for pointerenter/pointerleave and pointerover/pointerout
+//
+// Support: Safari 7 only
+// Safari sends mouseenter too often; see:
+// https://bugs.chromium.org/p/chromium/issues/detail?id=470258
+// for the description of the bug (it existed in older Chrome versions as well).
+jQuery.each( {
+       mouseenter: "mouseover",
+       mouseleave: "mouseout",
+       pointerenter: "pointerover",
+       pointerleave: "pointerout"
+}, function( orig, fix ) {
+       jQuery.event.special[ orig ] = {
+               delegateType: fix,
+               bindType: fix,
+
+               handle: function( event ) {
+                       var ret,
+                               target = this,
+                               related = event.relatedTarget,
+                               handleObj = event.handleObj;
+
+                       // For mouseenter/leave call the handler if related is outside the target.
+                       // NB: No relatedTarget if the mouse left/entered the browser window
+                       if ( !related || ( related !== target && !jQuery.contains( target, related ) ) ) {
+                               event.type = handleObj.origType;
+                               ret = handleObj.handler.apply( this, arguments );
+                               event.type = fix;
+                       }
+                       return ret;
+               }
+       };
+} );
+
+jQuery.fn.extend( {
+
+       on: function( types, selector, data, fn ) {
+               return on( this, types, selector, data, fn );
+       },
+       one: function( types, selector, data, fn ) {
+               return on( this, types, selector, data, fn, 1 );
+       },
+       off: function( types, selector, fn ) {
+               var handleObj, type;
+               if ( types && types.preventDefault && types.handleObj ) {
+
+                       // ( event )  dispatched jQuery.Event
+                       handleObj = types.handleObj;
+                       jQuery( types.delegateTarget ).off(
+                               handleObj.namespace ?
+                                       handleObj.origType + "." + handleObj.namespace :
+                                       handleObj.origType,
+                               handleObj.selector,
+                               handleObj.handler
+                       );
+                       return this;
+               }
+               if ( typeof types === "object" ) {
+
+                       // ( types-object [, selector] )
+                       for ( type in types ) {
+                               this.off( type, selector, types[ type ] );
+                       }
+                       return this;
+               }
+               if ( selector === false || typeof selector === "function" ) {
+
+                       // ( types [, fn] )
+                       fn = selector;
+                       selector = undefined;
+               }
+               if ( fn === false ) {
+                       fn = returnFalse;
+               }
+               return this.each( function() {
+                       jQuery.event.remove( this, types, fn, selector );
+               } );
+       }
+} );
+
+
+var
+
+       /* eslint-disable max-len */
+
+       // See https://github.com/eslint/eslint/issues/3229
+       rxhtmlTag = 
/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([a-z][^\/\0>\x20\t\r\n\f]*)[^>]*)\/>/gi,
+
+       /* eslint-enable */
+
+       // Support: IE <=10 - 11, Edge 12 - 13
+       // In IE/Edge using regex groups here causes severe slowdowns.
+       // See https://connect.microsoft.com/IE/feedback/details/1736512/
+       rnoInnerhtml = /<script|<style|<link/i,
+
+       // checked="checked" or checked
+       rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+       rscriptTypeMasked = /^true\/(.*)/,
+       rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;
+
+// Prefer a tbody over its parent table for containing new rows
+function manipulationTarget( elem, content ) {
+       if ( nodeName( elem, "table" ) &&
+               nodeName( content.nodeType !== 11 ? content : content.firstChild, "tr" ) ) {
+
+               return jQuery( ">tbody", elem )[ 0 ] || elem;
+       }
+
+       return elem;
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+       elem.type = ( elem.getAttribute( "type" ) !== null ) + "/" + elem.type;
+       return elem;
+}
+function restoreScript( elem ) {
+       var match = rscriptTypeMasked.exec( elem.type );
+
+       if ( match ) {
+               elem.type = match[ 1 ];
+       } else {
+               elem.removeAttribute( "type" );
+       }
+
+       return elem;
+}
+
+function cloneCopyEvent( src, dest ) {
+       var i, l, type, pdataOld, pdataCur, udataOld, udataCur, events;
+
+       if ( dest.nodeType !== 1 ) {
+               return;
+       }
+
+       // 1. Copy private data: events, handlers, etc.
+       if ( dataPriv.hasData( src ) ) {
+               pdataOld = dataPriv.access( src );
+               pdataCur = dataPriv.set( dest, pdataOld );
+               events = pdataOld.events;
+
+               if ( events ) {
+                       delete pdataCur.handle;
+                       pdataCur.events = {};
+
+                       for ( type in events ) {
+                               for ( i = 0, l = events[ type ].length; i < l; i++ ) {
+                                       jQuery.event.add( dest, type, events[ type ][ i ] );
+                               }
+                       }
+               }
+       }
+
+       // 2. Copy user data
+       if ( dataUser.hasData( src ) ) {
+               udataOld = dataUser.access( src );
+               udataCur = jQuery.extend( {}, udataOld );
+
+               dataUser.set( dest, udataCur );
+       }
+}
+
+// Fix IE bugs, see support tests
+function fixInput( src, dest ) {
+       var nodeName = dest.nodeName.toLowerCase();
+
+       // Fails to persist the checked state of a cloned checkbox or radio button.
+       if ( nodeName === "input" && rcheckableType.test( src.type ) ) {
+               dest.checked = src.checked;
+
+       // Fails to return the selected option to the default selected state when cloning options
+       } else if ( nodeName === "input" || nodeName === "textarea" ) {
+               dest.defaultValue = src.defaultValue;
+       }
+}
+
+function domManip( collection, args, callback, ignored ) {
+
+       // Flatten any nested arrays
+       args = concat.apply( [], args );
+
+       var fragment, first, scripts, hasScripts, node, doc,
+               i = 0,
+               l = collection.length,
+               iNoClone = l - 1,
+               value = args[ 0 ],
+               isFunction = jQuery.isFunction( value );
+
+       // We can't cloneNode fragments that contain checked, in WebKit
+       if ( isFunction ||
+                       ( l > 1 && typeof value === "string" &&
+                               !support.checkClone && rchecked.test( value ) ) ) {
+               return collection.each( function( index ) {
+                       var self = collection.eq( index );
+                       if ( isFunction ) {
+                               args[ 0 ] = value.call( this, index, self.html() );
+                       }
+                       domManip( self, args, callback, ignored );
+               } );
+       }
+
+       if ( l ) {
+               fragment = buildFragment( args, collection[ 0 ].ownerDocument, false, collection, ignored );
+               first = fragment.firstChild;
+
+               if ( fragment.childNodes.length === 1 ) {
+                       fragment = first;
+               }
+
+               // Require either new content or an interest in ignored elements to invoke the callback
+               if ( first || ignored ) {
+                       scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+                       hasScripts = scripts.length;
+
+                       // Use the original fragment for the last item
+                       // instead of the first because it can end up
+                       // being emptied incorrectly in certain situations (#8070).
+                       for ( ; i < l; i++ ) {
+                               node = fragment;
+
+                               if ( i !== iNoClone ) {
+                                       node = jQuery.clone( node, true, true );
+
+                                       // Keep references to cloned scripts for later restoration
+                                       if ( hasScripts ) {
+
+                                               // Support: Android <=4.0 only, PhantomJS 1 only
+                                               // push.apply(_, arraylike) throws on ancient WebKit
+                                               jQuery.merge( scripts, getAll( node, "script" ) );
+                                       }
+                               }
+
+                               callback.call( collection[ i ], node, i );
+                       }
+
+                       if ( hasScripts ) {
+                               doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+                               // Reenable scripts
+                               jQuery.map( scripts, restoreScript );
+
+                               // Evaluate executable scripts on first document insertion
+                               for ( i = 0; i < hasScripts; i++ ) {
+                                       node = scripts[ i ];
+                                       if ( rscriptType.test( node.type || "" ) &&
+                                               !dataPriv.access( node, "globalEval" ) &&
+                                               jQuery.contains( doc, node ) ) {
+
+                                               if ( node.src ) {
+
+                                                       // Optional AJAX dependency, but won't run scripts if 
not present
+                                                       if ( jQuery._evalUrl ) {
+                                                               jQuery._evalUrl( node.src );
+                                                       }
+                                               } else {
+                                                       DOMEval( node.textContent.replace( rcleanScript, "" 
), doc );
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return collection;
+}
+
+function remove( elem, selector, keepData ) {
+       var node,
+               nodes = selector ? jQuery.filter( selector, elem ) : elem,
+               i = 0;
+
+       for ( ; ( node = nodes[ i ] ) != null; i++ ) {
+               if ( !keepData && node.nodeType === 1 ) {
+                       jQuery.cleanData( getAll( node ) );
+               }
+
+               if ( node.parentNode ) {
+                       if ( keepData && jQuery.contains( node.ownerDocument, node ) ) {
+                               setGlobalEval( getAll( node, "script" ) );
+                       }
+                       node.parentNode.removeChild( node );
+               }
+       }
+
+       return elem;
+}
+
+jQuery.extend( {
+       htmlPrefilter: function( html ) {
+               return html.replace( rxhtmlTag, "<$1></$2>" );
+       },
+
+       clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+               var i, l, srcElements, destElements,
+                       clone = elem.cloneNode( true ),
+                       inPage = jQuery.contains( elem.ownerDocument, elem );
+
+               // Fix IE cloning issues
+               if ( !support.noCloneChecked && ( elem.nodeType === 1 || elem.nodeType === 11 ) &&
+                               !jQuery.isXMLDoc( elem ) ) {
+
+                       // We eschew Sizzle here for performance reasons: 
https://jsperf.com/getall-vs-sizzle/2
+                       destElements = getAll( clone );
+                       srcElements = getAll( elem );
+
+                       for ( i = 0, l = srcElements.length; i < l; i++ ) {
+                               fixInput( srcElements[ i ], destElements[ i ] );
+                       }
+               }
+
+               // Copy the events from the original to the clone
+               if ( dataAndEvents ) {
+                       if ( deepDataAndEvents ) {
+                               srcElements = srcElements || getAll( elem );
+                               destElements = destElements || getAll( clone );
+
+                               for ( i = 0, l = srcElements.length; i < l; i++ ) {
+                                       cloneCopyEvent( srcElements[ i ], destElements[ i ] );
+                               }
+                       } else {
+                               cloneCopyEvent( elem, clone );
+                       }
+               }
+
+               // Preserve script evaluation history
+               destElements = getAll( clone, "script" );
+               if ( destElements.length > 0 ) {
+                       setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+               }
+
+               // Return the cloned set
+               return clone;
+       },
+
+       cleanData: function( elems ) {
+               var data, elem, type,
+                       special = jQuery.event.special,
+                       i = 0;
+
+               for ( ; ( elem = elems[ i ] ) !== undefined; i++ ) {
+                       if ( acceptData( elem ) ) {
+                               if ( ( data = elem[ dataPriv.expando ] ) ) {
+                                       if ( data.events ) {
+                                               for ( type in data.events ) {
+                                                       if ( special[ type ] ) {
+                                                               jQuery.event.remove( elem, type );
+
+                                                       // This is a shortcut to avoid jQuery.event.remove's 
overhead
+                                                       } else {
+                                                               jQuery.removeEvent( elem, type, data.handle );
+                                                       }
+                                               }
+                                       }
+
+                                       // Support: Chrome <=35 - 45+
+                                       // Assign undefined instead of using delete, see Data#remove
+                                       elem[ dataPriv.expando ] = undefined;
+                               }
+                               if ( elem[ dataUser.expando ] ) {
+
+                                       // Support: Chrome <=35 - 45+
+                                       // Assign undefined instead of using delete, see Data#remove
+                                       elem[ dataUser.expando ] = undefined;
+                               }
+                       }
+               }
+       }
+} );
+
+jQuery.fn.extend( {
+       detach: function( selector ) {
+               return remove( this, selector, true );
+       },
+
+       remove: function( selector ) {
+               return remove( this, selector );
+       },
+
+       text: function( value ) {
+               return access( this, function( value ) {
+                       return value === undefined ?
+                               jQuery.text( this ) :
+                               this.empty().each( function() {
+                                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 
9 ) {
+                                               this.textContent = value;
+                                       }
+                               } );
+               }, null, value, arguments.length );
+       },
+
+       append: function() {
+               return domManip( this, arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.appendChild( elem );
+                       }
+               } );
+       },
+
+       prepend: function() {
+               return domManip( this, arguments, function( elem ) {
+                       if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+                               var target = manipulationTarget( this, elem );
+                               target.insertBefore( elem, target.firstChild );
+                       }
+               } );
+       },
+
+       before: function() {
+               return domManip( this, arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this );
+                       }
+               } );
+       },
+
+       after: function() {
+               return domManip( this, arguments, function( elem ) {
+                       if ( this.parentNode ) {
+                               this.parentNode.insertBefore( elem, this.nextSibling );
+                       }
+               } );
+       },
+
+       empty: function() {
+               var elem,
+                       i = 0;
+
+               for ( ; ( elem = this[ i ] ) != null; i++ ) {
+                       if ( elem.nodeType === 1 ) {
+
+                               // Prevent memory leaks
+                               jQuery.cleanData( getAll( elem, false ) );
+
+                               // Remove any remaining nodes
+                               elem.textContent = "";
+                       }
+               }
+
+               return this;
+       },
+
+       clone: function( dataAndEvents, deepDataAndEvents ) {
+               dataAndEvents = dataAndEvents == null ? false : dataAndEvents;
+               deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents;
+
+               return this.map( function() {
+                       return jQuery.clone( this, dataAndEvents, deepDataAndEvents );
+               } );
+       },
+
+       html: function( value ) {
+               return access( this, function( value ) {
+                       var elem = this[ 0 ] || {},
+                               i = 0,
+                               l = this.length;
+
+                       if ( value === undefined && elem.nodeType === 1 ) {
+                               return elem.innerHTML;
+                       }
+
+                       // See if we can take a shortcut and just use innerHTML
+                       if ( typeof value === "string" && !rnoInnerhtml.test( value ) &&
+                               !wrapMap[ ( rtagName.exec( value ) || [ "", "" ] )[ 1 ].toLowerCase() ] ) {
+
+                               value = jQuery.htmlPrefilter( value );
+
+                               try {
+                                       for ( ; i < l; i++ ) {
+                                               elem = this[ i ] || {};
+
+                                               // Remove element nodes and prevent memory leaks
+                                               if ( elem.nodeType === 1 ) {
+                                                       jQuery.cleanData( getAll( elem, false ) );
+                                                       elem.innerHTML = value;
+                                               }
+                                       }
+
+                                       elem = 0;
+
+                               // If using innerHTML throws an exception, use the fallback method
+                               } catch ( e ) {}
+                       }
+
+                       if ( elem ) {
+                               this.empty().append( value );
+                       }
+               }, null, value, arguments.length );
+       },
+
+       replaceWith: function() {
+               var ignored = [];
+
+               // Make the changes, replacing each non-ignored context element with the new content
+               return domManip( this, arguments, function( elem ) {
+                       var parent = this.parentNode;
+
+                       if ( jQuery.inArray( this, ignored ) < 0 ) {
+                               jQuery.cleanData( getAll( this ) );
+                               if ( parent ) {
+                                       parent.replaceChild( elem, this );
+                               }
+                       }
+
+               // Force callback invocation
+               }, ignored );
+       }
+} );
+
+jQuery.each( {
+       appendTo: "append",
+       prependTo: "prepend",
+       insertBefore: "before",
+       insertAfter: "after",
+       replaceAll: "replaceWith"
+}, function( name, original ) {
+       jQuery.fn[ name ] = function( selector ) {
+               var elems,
+                       ret = [],
+                       insert = jQuery( selector ),
+                       last = insert.length - 1,
+                       i = 0;
+
+               for ( ; i <= last; i++ ) {
+                       elems = i === last ? this : this.clone( true );
+                       jQuery( insert[ i ] )[ original ]( elems );
+
+                       // Support: Android <=4.0 only, PhantomJS 1 only
+                       // .get() because push.apply(_, arraylike) throws on ancient WebKit
+                       push.apply( ret, elems.get() );
+               }
+
+               return this.pushStack( ret );
+       };
+} );
+var rmargin = ( /^margin/ );
+
+var rnumnonpx = new RegExp( "^(" + pnum + ")(?!px)[a-z%]+$", "i" );
+
+var getStyles = function( elem ) {
+
+               // Support: IE <=11 only, Firefox <=30 (#15098, #14150)
+               // IE throws on elements created in popups
+               // FF meanwhile throws on frame elements through "defaultView.getComputedStyle"
+               var view = elem.ownerDocument.defaultView;
+
+               if ( !view || !view.opener ) {
+                       view = window;
+               }
+
+               return view.getComputedStyle( elem );
+       };
+
+
+
+( function() {
+
+       // Executing both pixelPosition & boxSizingReliable tests require only one layout
+       // so they're executed at the same time to save the second computation.
+       function computeStyleTests() {
+
+               // This is a singleton, we need to execute it only once
+               if ( !div ) {
+                       return;
+               }
+
+               div.style.cssText =
+                       "box-sizing:border-box;" +
+                       "position:relative;display:block;" +
+                       "margin:auto;border:1px;padding:1px;" +
+                       "top:1%;width:50%";
+               div.innerHTML = "";
+               documentElement.appendChild( container );
+
+               var divStyle = window.getComputedStyle( div );
+               pixelPositionVal = divStyle.top !== "1%";
+
+               // Support: Android 4.0 - 4.3 only, Firefox <=3 - 44
+               reliableMarginLeftVal = divStyle.marginLeft === "2px";
+               boxSizingReliableVal = divStyle.width === "4px";
+
+               // Support: Android 4.0 - 4.3 only
+               // Some styles come back with percentage values, even though they shouldn't
+               div.style.marginRight = "50%";
+               pixelMarginRightVal = divStyle.marginRight === "4px";
+
+               documentElement.removeChild( container );
+
+               // Nullify the div so it wouldn't be stored in the memory and
+               // it will also be a sign that checks already performed
+               div = null;
+       }
+
+       var pixelPositionVal, boxSizingReliableVal, pixelMarginRightVal, reliableMarginLeftVal,
+               container = document.createElement( "div" ),
+               div = document.createElement( "div" );
+
+       // Finish early in limited (non-browser) environments
+       if ( !div.style ) {
+               return;
+       }
+
+       // Support: IE <=9 - 11 only
+       // Style of cloned element affects source element cloned (#8908)
+       div.style.backgroundClip = "content-box";
+       div.cloneNode( true ).style.backgroundClip = "";
+       support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+       container.style.cssText = "border:0;width:8px;height:0;top:0;left:-9999px;" +
+               "padding:0;margin-top:1px;position:absolute";
+       container.appendChild( div );
+
+       jQuery.extend( support, {
+               pixelPosition: function() {
+                       computeStyleTests();
+                       return pixelPositionVal;
+               },
+               boxSizingReliable: function() {
+                       computeStyleTests();
+                       return boxSizingReliableVal;
+               },
+               pixelMarginRight: function() {
+                       computeStyleTests();
+                       return pixelMarginRightVal;
+               },
+               reliableMarginLeft: function() {
+                       computeStyleTests();
+                       return reliableMarginLeftVal;
+               }
+       } );
+} )();
+
+
+function curCSS( elem, name, computed ) {
+       var width, minWidth, maxWidth, ret,
+
+               // Support: Firefox 51+
+               // Retrieving style before computed somehow
+               // fixes an issue with getting wrong values
+               // on detached elements
+               style = elem.style;
+
+       computed = computed || getStyles( elem );
+
+       // getPropertyValue is needed for:
+       //   .css('filter') (IE 9 only, #12537)
+       //   .css('--customProperty) (#3144)
+       if ( computed ) {
+               ret = computed.getPropertyValue( name ) || computed[ name ];
+
+               if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) {
+                       ret = jQuery.style( elem, name );
+               }
+
+               // A tribute to the "awesome hack by Dean Edwards"
+               // Android Browser returns percentage for some values,
+               // but width seems to be reliably pixels.
+               // This is against the CSSOM draft spec:
+               // https://drafts.csswg.org/cssom/#resolved-values
+               if ( !support.pixelMarginRight() && rnumnonpx.test( ret ) && rmargin.test( name ) ) {
+
+                       // Remember the original values
+                       width = style.width;
+                       minWidth = style.minWidth;
+                       maxWidth = style.maxWidth;
+
+                       // Put in the new values to get a computed value out
+                       style.minWidth = style.maxWidth = style.width = ret;
+                       ret = computed.width;
+
+                       // Revert the changed values
+                       style.width = width;
+                       style.minWidth = minWidth;
+                       style.maxWidth = maxWidth;
+               }
+       }
+
+       return ret !== undefined ?
+
+               // Support: IE <=9 - 11 only
+               // IE returns zIndex value as an integer.
+               ret + "" :
+               ret;
+}
+
+
+function addGetHookIf( conditionFn, hookFn ) {
+
+       // Define the hook, we'll check on the first run if it's really needed.
+       return {
+               get: function() {
+                       if ( conditionFn() ) {
+
+                               // Hook not needed (or it's not possible to use it due
+                               // to missing dependency), remove it.
+                               delete this.get;
+                               return;
+                       }
+
+                       // Hook needed; redefine it so that the support test is not executed again.
+                       return ( this.get = hookFn ).apply( this, arguments );
+               }
+       };
+}
+
+
+var
+
+       // Swappable if display is none or starts with table
+       // except "table", "table-cell", or "table-caption"
+       // See here for display values: https://developer.mozilla.org/en-US/docs/CSS/display
+       rdisplayswap = /^(none|table(?!-c[ea]).+)/,
+       rcustomProp = /^--/,
+       cssShow = { position: "absolute", visibility: "hidden", display: "block" },
+       cssNormalTransform = {
+               letterSpacing: "0",
+               fontWeight: "400"
+       },
+
+       cssPrefixes = [ "Webkit", "Moz", "ms" ],
+       emptyStyle = document.createElement( "div" ).style;
+
+// Return a css property mapped to a potentially vendor prefixed property
+function vendorPropName( name ) {
+
+       // Shortcut for names that are not vendor prefixed
+       if ( name in emptyStyle ) {
+               return name;
+       }
+
+       // Check for vendor prefixed names
+       var capName = name[ 0 ].toUpperCase() + name.slice( 1 ),
+               i = cssPrefixes.length;
+
+       while ( i-- ) {
+               name = cssPrefixes[ i ] + capName;
+               if ( name in emptyStyle ) {
+                       return name;
+               }
+       }
+}
+
+// Return a property mapped along what jQuery.cssProps suggests or to
+// a vendor prefixed property.
+function finalPropName( name ) {
+       var ret = jQuery.cssProps[ name ];
+       if ( !ret ) {
+               ret = jQuery.cssProps[ name ] = vendorPropName( name ) || name;
+       }
+       return ret;
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+
+       // Any relative (+/-) values have already been
+       // normalized at this point
+       var matches = rcssNum.exec( value );
+       return matches ?
+
+               // Guard against undefined "subtract", e.g., when used as in cssHooks
+               Math.max( 0, matches[ 2 ] - ( subtract || 0 ) ) + ( matches[ 3 ] || "px" ) :
+               value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+       var i,
+               val = 0;
+
+       // If we already have the right measurement, avoid augmentation
+       if ( extra === ( isBorderBox ? "border" : "content" ) ) {
+               i = 4;
+
+       // Otherwise initialize for horizontal or vertical properties
+       } else {
+               i = name === "width" ? 1 : 0;
+       }
+
+       for ( ; i < 4; i += 2 ) {
+
+               // Both box models exclude margin, so add it if we want it
+               if ( extra === "margin" ) {
+                       val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+               }
+
+               if ( isBorderBox ) {
+
+                       // border-box includes padding, so remove it if we want content
+                       if ( extra === "content" ) {
+                               val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+                       }
+
+                       // At this point, extra isn't border nor margin, so remove border
+                       if ( extra !== "margin" ) {
+                               val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               } else {
+
+                       // At this point, extra isn't content, so add padding
+                       val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+                       // At this point, extra isn't content nor padding, so add border
+                       if ( extra !== "padding" ) {
+                               val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+                       }
+               }
+       }
+
+       return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+       // Start with computed style
+       var valueIsBorderBox,
+               styles = getStyles( elem ),
+               val = curCSS( elem, name, styles ),
+               isBorderBox = jQuery.css( elem, "boxSizing", false, styles ) === "border-box";
+
+       // Computed unit is not pixels. Stop here and return.
+       if ( rnumnonpx.test( val ) ) {
+               return val;
+       }
+
+       // Check for style in case a browser which returns unreliable values
+       // for getComputedStyle silently falls back to the reliable elem.style
+       valueIsBorderBox = isBorderBox &&
+               ( support.boxSizingReliable() || val === elem.style[ name ] );
+
+       // Fall back to offsetWidth/Height when value is "auto"
+       // This happens for inline elements with no explicit setting (gh-3571)
+       if ( val === "auto" ) {
+               val = elem[ "offset" + name[ 0 ].toUpperCase() + name.slice( 1 ) ];
+       }
+
+       // Normalize "", auto, and prepare for extra
+       val = parseFloat( val ) || 0;
+
+       // Use the active box-sizing model to add/subtract irrelevant styles
+       return ( val +
+               augmentWidthOrHeight(
+                       elem,
+                       name,
+                       extra || ( isBorderBox ? "border" : "content" ),
+                       valueIsBorderBox,
+                       styles
+               )
+       ) + "px";
+}
+
+jQuery.extend( {
+
+       // Add in style property hooks for overriding the default
+       // behavior of getting and setting a style property
+       cssHooks: {
+               opacity: {
+                       get: function( elem, computed ) {
+                               if ( computed ) {
+
+                                       // We should always get a number back from opacity
+                                       var ret = curCSS( elem, "opacity" );
+                                       return ret === "" ? "1" : ret;
+                               }
+                       }
+               }
+       },
+
+       // Don't automatically add "px" to these possibly-unitless properties
+       cssNumber: {
+               "animationIterationCount": true,
+               "columnCount": true,
+               "fillOpacity": true,
+               "flexGrow": true,
+               "flexShrink": true,
+               "fontWeight": true,
+               "lineHeight": true,
+               "opacity": true,
+               "order": true,
+               "orphans": true,
+               "widows": true,
+               "zIndex": true,
+               "zoom": true
+       },
+
+       // Add in properties whose names you wish to fix before
+       // setting or getting the value
+       cssProps: {
+               "float": "cssFloat"
+       },
+
+       // Get and set the style property on a DOM Node
+       style: function( elem, name, value, extra ) {
+
+               // Don't set styles on text and comment nodes
+               if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) {
+                       return;
+               }
+
+               // Make sure that we're working with the right name
+               var ret, type, hooks,
+                       origName = jQuery.camelCase( name ),
+                       isCustomProp = rcustomProp.test( name ),
+                       style = elem.style;
+
+               // Make sure that we're working with the right name. We don't
+               // want to query the value if it is a CSS custom property
+               // since they are user-defined.
+               if ( !isCustomProp ) {
+                       name = finalPropName( origName );
+               }
+
+               // Gets hook for the prefixed version, then unprefixed version
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // Check if we're setting a value
+               if ( value !== undefined ) {
+                       type = typeof value;
+
+                       // Convert "+=" or "-=" to relative numbers (#7345)
+                       if ( type === "string" && ( ret = rcssNum.exec( value ) ) && ret[ 1 ] ) {
+                               value = adjustCSS( elem, name, ret );
+
+                               // Fixes bug #9237
+                               type = "number";
+                       }
+
+                       // Make sure that null and NaN values aren't set (#7116)
+                       if ( value == null || value !== value ) {
+                               return;
+                       }
+
+                       // If a number was passed in, add the unit (except for certain CSS properties)
+                       if ( type === "number" ) {
+                               value += ret && ret[ 3 ] || ( jQuery.cssNumber[ origName ] ? "" : "px" );
+                       }
+
+                       // background-* props affect original clone's values
+                       if ( !support.clearCloneStyle && value === "" && name.indexOf( "background" ) === 0 ) 
{
+                               style[ name ] = "inherit";
+                       }
+
+                       // If a hook was provided, use that value, otherwise just set the specified value
+                       if ( !hooks || !( "set" in hooks ) ||
+                               ( value = hooks.set( elem, value, extra ) ) !== undefined ) {
+
+                               if ( isCustomProp ) {
+                                       style.setProperty( name, value );
+                               } else {
+                                       style[ name ] = value;
+                               }
+                       }
+
+               } else {
+
+                       // If a hook was provided get the non-computed value from there
+                       if ( hooks && "get" in hooks &&
+                               ( ret = hooks.get( elem, false, extra ) ) !== undefined ) {
+
+                               return ret;
+                       }
+
+                       // Otherwise just get the value from the style object
+                       return style[ name ];
+               }
+       },
+
+       css: function( elem, name, extra, styles ) {
+               var val, num, hooks,
+                       origName = jQuery.camelCase( name ),
+                       isCustomProp = rcustomProp.test( name );
+
+               // Make sure that we're working with the right name. We don't
+               // want to modify the value if it is a CSS custom property
+               // since they are user-defined.
+               if ( !isCustomProp ) {
+                       name = finalPropName( origName );
+               }
+
+               // Try prefixed name followed by the unprefixed name
+               hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ];
+
+               // If a hook was provided get the computed value from there
+               if ( hooks && "get" in hooks ) {
+                       val = hooks.get( elem, true, extra );
+               }
+
+               // Otherwise, if a way to get the computed value exists, use that
+               if ( val === undefined ) {
+                       val = curCSS( elem, name, styles );
+               }
+
+               // Convert "normal" to computed value
+               if ( val === "normal" && name in cssNormalTransform ) {
+                       val = cssNormalTransform[ name ];
+               }
+
+               // Make numeric if forced or a qualifier was provided and val looks numeric
+               if ( extra === "" || extra ) {
+                       num = parseFloat( val );
+                       return extra === true || isFinite( num ) ? num || 0 : val;
+               }
+
+               return val;
+       }
+} );
+
+jQuery.each( [ "height", "width" ], function( i, name ) {
+       jQuery.cssHooks[ name ] = {
+               get: function( elem, computed, extra ) {
+                       if ( computed ) {
+
+                               // Certain elements can have dimension info if we invisibly show them
+                               // but it must have a current display style that would benefit
+                               return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
+
+                                       // Support: Safari 8+
+                                       // Table columns in Safari have non-zero offsetWidth & zero
+                                       // getBoundingClientRect().width unless display is changed.
+                                       // Support: IE <=11 only
+                                       // Running getBoundingClientRect on a disconnected node
+                                       // in IE throws an error.
+                                       ( !elem.getClientRects().length || 
!elem.getBoundingClientRect().width ) ?
+                                               swap( elem, cssShow, function() {
+                                                       return getWidthOrHeight( elem, name, extra );
+                                               } ) :
+                                               getWidthOrHeight( elem, name, extra );
+                       }
+               },
+
+               set: function( elem, value, extra ) {
+                       var matches,
+                               styles = extra && getStyles( elem ),
+                               subtract = extra && augmentWidthOrHeight(
+                                       elem,
+                                       name,
+                                       extra,
+                                       jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+                                       styles
+                               );
+
+                       // Convert to pixels if value adjustment is needed
+                       if ( subtract && ( matches = rcssNum.exec( value ) ) &&
+                               ( matches[ 3 ] || "px" ) !== "px" ) {
+
+                               elem.style[ name ] = value;
+                               value = jQuery.css( elem, name );
+                       }
+
+                       return setPositiveNumber( elem, value, subtract );
+               }
+       };
+} );
+
+jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
+       function( elem, computed ) {
+               if ( computed ) {
+                       return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
+                               elem.getBoundingClientRect().left -
+                                       swap( elem, { marginLeft: 0 }, function() {
+                                               return elem.getBoundingClientRect().left;
+                                       } )
+                               ) + "px";
+               }
+       }
+);
+
+// These hooks are used by animate to expand properties
+jQuery.each( {
+       margin: "",
+       padding: "",
+       border: "Width"
+}, function( prefix, suffix ) {
+       jQuery.cssHooks[ prefix + suffix ] = {
+               expand: function( value ) {
+                       var i = 0,
+                               expanded = {},
+
+                               // Assumes a single number if not a string
+                               parts = typeof value === "string" ? value.split( " " ) : [ value ];
+
+                       for ( ; i < 4; i++ ) {
+                               expanded[ prefix + cssExpand[ i ] + suffix ] =
+                                       parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
+                       }
+
+                       return expanded;
+               }
+       };
+
+       if ( !rmargin.test( prefix ) ) {
+               jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
+       }
+} );
+
+jQuery.fn.extend( {
+       css: function( name, value ) {
+               return access( this, function( elem, name, value ) {
+                       var styles, len,
+                               map = {},
+                               i = 0;
+
+                       if ( Array.isArray( name ) ) {
+                               styles = getStyles( elem );
+                               len = name.length;
+
+                               for ( ; i < len; i++ ) {
+                                       map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+                               }
+
+                               return map;
+                       }
+
+                       return value !== undefined ?
+                               jQuery.style( elem, name, value ) :
+                               jQuery.css( elem, name );
+               }, name, value, arguments.length > 1 );
+       }
+} );
+
+
+function Tween( elem, options, prop, end, easing ) {
+       return new Tween.prototype.init( elem, options, prop, end, easing );
+}
+jQuery.Tween = Tween;
+
+Tween.prototype = {
+       constructor: Tween,
+       init: function( elem, options, prop, end, easing, unit ) {
+               this.elem = elem;
+               this.prop = prop;
+               this.easing = easing || jQuery.easing._default;
+               this.options = options;
+               this.start = this.now = this.cur();
+               this.end = end;
+               this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
+       },
+       cur: function() {
+               var hooks = Tween.propHooks[ this.prop ];
+
+               return hooks && hooks.get ?
+                       hooks.get( this ) :
+                       Tween.propHooks._default.get( this );
+       },
+       run: function( percent ) {
+               var eased,
+                       hooks = Tween.propHooks[ this.prop ];
+
+               if ( this.options.duration ) {
+                       this.pos = eased = jQuery.easing[ this.easing ](
+                               percent, this.options.duration * percent, 0, 1, this.options.duration
+                       );
+               } else {
+                       this.pos = eased = percent;
+               }
+               this.now = ( this.end - this.start ) * eased + this.start;
+
+               if ( this.options.step ) {
+                       this.options.step.call( this.elem, this.now, this );
+               }
+
+               if ( hooks && hooks.set ) {
+                       hooks.set( this );
+               } else {
+                       Tween.propHooks._default.set( this );
+               }
+               return this;
+       }
+};
+
+Tween.prototype.init.prototype = Tween.prototype;
+
+Tween.propHooks = {
+       _default: {
+               get: function( tween ) {
+                       var result;
+
+                       // Use a property on the element directly when it is not a DOM element,
+                       // or when there is no matching style property that exists.
+                       if ( tween.elem.nodeType !== 1 ||
+                               tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
+                               return tween.elem[ tween.prop ];
+                       }
+
+                       // Passing an empty string as a 3rd parameter to .css will automatically
+                       // attempt a parseFloat and fallback to a string if the parse fails.
+                       // Simple values such as "10px" are parsed to Float;
+                       // complex values such as "rotate(1rad)" are returned as-is.
+                       result = jQuery.css( tween.elem, tween.prop, "" );
+
+                       // Empty strings, null, undefined and "auto" are converted to 0.
+                       return !result || result === "auto" ? 0 : result;
+               },
+               set: function( tween ) {
+
+                       // Use step hook for back compat.
+                       // Use cssHook if its there.
+                       // Use .style if available and use plain properties where available.
+                       if ( jQuery.fx.step[ tween.prop ] ) {
+                               jQuery.fx.step[ tween.prop ]( tween );
+                       } else if ( tween.elem.nodeType === 1 &&
+                               ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null ||
+                                       jQuery.cssHooks[ tween.prop ] ) ) {
+                               jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
+                       } else {
+                               tween.elem[ tween.prop ] = tween.now;
+                       }
+               }
+       }
+};
+
+// Support: IE <=9 only
+// Panic based approach to setting things on disconnected nodes
+Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
+       set: function( tween ) {
+               if ( tween.elem.nodeType && tween.elem.parentNode ) {
+                       tween.elem[ tween.prop ] = tween.now;
+               }
+       }
+};
+
+jQuery.easing = {
+       linear: function( p ) {
+               return p;
+       },
+       swing: function( p ) {
+               return 0.5 - Math.cos( p * Math.PI ) / 2;
+       },
+       _default: "swing"
+};
+
+jQuery.fx = Tween.prototype.init;
+
+// Back compat <1.8 extension point
+jQuery.fx.step = {};
+
+
+
+
+var
+       fxNow, inProgress,
+       rfxtypes = /^(?:toggle|show|hide)$/,
+       rrun = /queueHooks$/;
+
+function schedule() {
+       if ( inProgress ) {
+               if ( document.hidden === false && window.requestAnimationFrame ) {
+                       window.requestAnimationFrame( schedule );
+               } else {
+                       window.setTimeout( schedule, jQuery.fx.interval );
+               }
+
+               jQuery.fx.tick();
+       }
+}
+
+// Animations created synchronously will run synchronously
+function createFxNow() {
+       window.setTimeout( function() {
+               fxNow = undefined;
+       } );
+       return ( fxNow = jQuery.now() );
+}
+
+// Generate parameters to create a standard animation
+function genFx( type, includeWidth ) {
+       var which,
+               i = 0,
+               attrs = { height: type };
+
+       // If we include width, step value is 1 to do all cssExpand values,
+       // otherwise step value is 2 to skip over Left and Right
+       includeWidth = includeWidth ? 1 : 0;
+       for ( ; i < 4; i += 2 - includeWidth ) {
+               which = cssExpand[ i ];
+               attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
+       }
+
+       if ( includeWidth ) {
+               attrs.opacity = attrs.width = type;
+       }
+
+       return attrs;
+}
+
+function createTween( value, prop, animation ) {
+       var tween,
+               collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
+               index = 0,
+               length = collection.length;
+       for ( ; index < length; index++ ) {
+               if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
+
+                       // We're done with this property
+                       return tween;
+               }
+       }
+}
+
+function defaultPrefilter( elem, props, opts ) {
+       var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
+               isBox = "width" in props || "height" in props,
+               anim = this,
+               orig = {},
+               style = elem.style,
+               hidden = elem.nodeType && isHiddenWithinTree( elem ),
+               dataShow = dataPriv.get( elem, "fxshow" );
+
+       // Queue-skipping animations hijack the fx hooks
+       if ( !opts.queue ) {
+               hooks = jQuery._queueHooks( elem, "fx" );
+               if ( hooks.unqueued == null ) {
+                       hooks.unqueued = 0;
+                       oldfire = hooks.empty.fire;
+                       hooks.empty.fire = function() {
+                               if ( !hooks.unqueued ) {
+                                       oldfire();
+                               }
+                       };
+               }
+               hooks.unqueued++;
+
+               anim.always( function() {
+
+                       // Ensure the complete handler is called before this completes
+                       anim.always( function() {
+                               hooks.unqueued--;
+                               if ( !jQuery.queue( elem, "fx" ).length ) {
+                                       hooks.empty.fire();
+                               }
+                       } );
+               } );
+       }
+
+       // Detect show/hide animations
+       for ( prop in props ) {
+               value = props[ prop ];
+               if ( rfxtypes.test( value ) ) {
+                       delete props[ prop ];
+                       toggle = toggle || value === "toggle";
+                       if ( value === ( hidden ? "hide" : "show" ) ) {
+
+                               // Pretend to be hidden if this is a "show" and
+                               // there is still data from a stopped show/hide
+                               if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
+                                       hidden = true;
+
+                               // Ignore all other no-op show/hide data
+                               } else {
+                                       continue;
+                               }
+                       }
+                       orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
+               }
+       }
+
+       // Bail out if this is a no-op like .hide().hide()
+       propTween = !jQuery.isEmptyObject( props );
+       if ( !propTween && jQuery.isEmptyObject( orig ) ) {
+               return;
+       }
+
+       // Restrict "overflow" and "display" styles during box animations
+       if ( isBox && elem.nodeType === 1 ) {
+
+               // Support: IE <=9 - 11, Edge 12 - 13
+               // Record all 3 overflow attributes because IE does not infer the shorthand
+               // from identically-valued overflowX and overflowY
+               opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
+
+               // Identify a display type, preferring old show/hide data over the CSS cascade
+               restoreDisplay = dataShow && dataShow.display;
+               if ( restoreDisplay == null ) {
+                       restoreDisplay = dataPriv.get( elem, "display" );
+               }
+               display = jQuery.css( elem, "display" );
+               if ( display === "none" ) {
+                       if ( restoreDisplay ) {
+                               display = restoreDisplay;
+                       } else {
+
+                               // Get nonempty value(s) by temporarily forcing visibility
+                               showHide( [ elem ], true );
+                               restoreDisplay = elem.style.display || restoreDisplay;
+                               display = jQuery.css( elem, "display" );
+                               showHide( [ elem ] );
+                       }
+               }
+
+               // Animate inline elements as inline-block
+               if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
+                       if ( jQuery.css( elem, "float" ) === "none" ) {
+
+                               // Restore the original display value at the end of pure show/hide animations
+                               if ( !propTween ) {
+                                       anim.done( function() {
+                                               style.display = restoreDisplay;
+                                       } );
+                                       if ( restoreDisplay == null ) {
+                                               display = style.display;
+                                               restoreDisplay = display === "none" ? "" : display;
+                                       }
+                               }
+                               style.display = "inline-block";
+                       }
+               }
+       }
+
+       if ( opts.overflow ) {
+               style.overflow = "hidden";
+               anim.always( function() {
+                       style.overflow = opts.overflow[ 0 ];
+                       style.overflowX = opts.overflow[ 1 ];
+                       style.overflowY = opts.overflow[ 2 ];
+               } );
+       }
+
+       // Implement show/hide animations
+       propTween = false;
+       for ( prop in orig ) {
+
+               // General show/hide setup for this element animation
+               if ( !propTween ) {
+                       if ( dataShow ) {
+                               if ( "hidden" in dataShow ) {
+                                       hidden = dataShow.hidden;
+                               }
+                       } else {
+                               dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
+                       }
+
+                       // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
+                       if ( toggle ) {
+                               dataShow.hidden = !hidden;
+                       }
+
+                       // Show elements before animating them
+                       if ( hidden ) {
+                               showHide( [ elem ], true );
+                       }
+
+                       /* eslint-disable no-loop-func */
+
+                       anim.done( function() {
+
+                       /* eslint-enable no-loop-func */
+
+                               // The final step of a "hide" animation is actually hiding the element
+                               if ( !hidden ) {
+                                       showHide( [ elem ] );
+                               }
+                               dataPriv.remove( elem, "fxshow" );
+                               for ( prop in orig ) {
+                                       jQuery.style( elem, prop, orig[ prop ] );
+                               }
+                       } );
+               }
+
+               // Per-property setup
+               propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
+               if ( !( prop in dataShow ) ) {
+                       dataShow[ prop ] = propTween.start;
+                       if ( hidden ) {
+                               propTween.end = propTween.start;
+                               propTween.start = 0;
+                       }
+               }
+       }
+}
+
+function propFilter( props, specialEasing ) {
+       var index, name, easing, value, hooks;
+
+       // camelCase, specialEasing and expand cssHook pass
+       for ( index in props ) {
+               name = jQuery.camelCase( index );
+               easing = specialEasing[ name ];
+               value = props[ index ];
+               if ( Array.isArray( value ) ) {
+                       easing = value[ 1 ];
+                       value = props[ index ] = value[ 0 ];
+               }
+
+               if ( index !== name ) {
+                       props[ name ] = value;
+                       delete props[ index ];
+               }
+
+               hooks = jQuery.cssHooks[ name ];
+               if ( hooks && "expand" in hooks ) {
+                       value = hooks.expand( value );
+                       delete props[ name ];
+
+                       // Not quite $.extend, this won't overwrite existing keys.
+                       // Reusing 'index' because we have the correct "name"
+                       for ( index in value ) {
+                               if ( !( index in props ) ) {
+                                       props[ index ] = value[ index ];
+                                       specialEasing[ index ] = easing;
+                               }
+                       }
+               } else {
+                       specialEasing[ name ] = easing;
+               }
+       }
+}
+
+function Animation( elem, properties, options ) {
+       var result,
+               stopped,
+               index = 0,
+               length = Animation.prefilters.length,
+               deferred = jQuery.Deferred().always( function() {
+
+                       // Don't match elem in the :animated selector
+                       delete tick.elem;
+               } ),
+               tick = function() {
+                       if ( stopped ) {
+                               return false;
+                       }
+                       var currentTime = fxNow || createFxNow(),
+                               remaining = Math.max( 0, animation.startTime + animation.duration - 
currentTime ),
+
+                               // Support: Android 2.3 only
+                               // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497)
+                               temp = remaining / animation.duration || 0,
+                               percent = 1 - temp,
+                               index = 0,
+                               length = animation.tweens.length;
+
+                       for ( ; index < length; index++ ) {
+                               animation.tweens[ index ].run( percent );
+                       }
+
+                       deferred.notifyWith( elem, [ animation, percent, remaining ] );
+
+                       // If there's more to do, yield
+                       if ( percent < 1 && length ) {
+                               return remaining;
+                       }
+
+                       // If this was an empty animation, synthesize a final progress notification
+                       if ( !length ) {
+                               deferred.notifyWith( elem, [ animation, 1, 0 ] );
+                       }
+
+                       // Resolve the animation and report its conclusion
+                       deferred.resolveWith( elem, [ animation ] );
+                       return false;
+               },
+               animation = deferred.promise( {
+                       elem: elem,
+                       props: jQuery.extend( {}, properties ),
+                       opts: jQuery.extend( true, {
+                               specialEasing: {},
+                               easing: jQuery.easing._default
+                       }, options ),
+                       originalProperties: properties,
+                       originalOptions: options,
+                       startTime: fxNow || createFxNow(),
+                       duration: options.duration,
+                       tweens: [],
+                       createTween: function( prop, end ) {
+                               var tween = jQuery.Tween( elem, animation.opts, prop, end,
+                                               animation.opts.specialEasing[ prop ] || animation.opts.easing 
);
+                               animation.tweens.push( tween );
+                               return tween;
+                       },
+                       stop: function( gotoEnd ) {
+                               var index = 0,
+
+                                       // If we are going to the end, we want to run all the tweens
+                                       // otherwise we skip this part
+                                       length = gotoEnd ? animation.tweens.length : 0;
+                               if ( stopped ) {
+                                       return this;
+                               }
+                               stopped = true;
+                               for ( ; index < length; index++ ) {
+                                       animation.tweens[ index ].run( 1 );
+                               }
+
+                               // Resolve when we played the last frame; otherwise, reject
+                               if ( gotoEnd ) {
+                                       deferred.notifyWith( elem, [ animation, 1, 0 ] );
+                                       deferred.resolveWith( elem, [ animation, gotoEnd ] );
+                               } else {
+                                       deferred.rejectWith( elem, [ animation, gotoEnd ] );
+                               }
+                               return this;
+                       }
+               } ),
+               props = animation.props;
+
+       propFilter( props, animation.opts.specialEasing );
+
+       for ( ; index < length; index++ ) {
+               result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts );
+               if ( result ) {
+                       if ( jQuery.isFunction( result.stop ) ) {
+                               jQuery._queueHooks( animation.elem, animation.opts.queue ).stop =
+                                       jQuery.proxy( result.stop, result );
+                       }
+                       return result;
+               }
+       }
+
+       jQuery.map( props, createTween, animation );
+
+       if ( jQuery.isFunction( animation.opts.start ) ) {
+               animation.opts.start.call( elem, animation );
+       }
+
+       // Attach callbacks from options
+       animation
+               .progress( animation.opts.progress )
+               .done( animation.opts.done, animation.opts.complete )
+               .fail( animation.opts.fail )
+               .always( animation.opts.always );
+
+       jQuery.fx.timer(
+               jQuery.extend( tick, {
+                       elem: elem,
+                       anim: animation,
+                       queue: animation.opts.queue
+               } )
+       );
+
+       return animation;
+}
+
+jQuery.Animation = jQuery.extend( Animation, {
+
+       tweeners: {
+               "*": [ function( prop, value ) {
+                       var tween = this.createTween( prop, value );
+                       adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween );
+                       return tween;
+               } ]
+       },
+
+       tweener: function( props, callback ) {
+               if ( jQuery.isFunction( props ) ) {
+                       callback = props;
+                       props = [ "*" ];
+               } else {
+                       props = props.match( rnothtmlwhite );
+               }
+
+               var prop,
+                       index = 0,
+                       length = props.length;
+
+               for ( ; index < length; index++ ) {
+                       prop = props[ index ];
+                       Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || [];
+                       Animation.tweeners[ prop ].unshift( callback );
+               }
+       },
+
+       prefilters: [ defaultPrefilter ],
+
+       prefilter: function( callback, prepend ) {
+               if ( prepend ) {
+                       Animation.prefilters.unshift( callback );
+               } else {
+                       Animation.prefilters.push( callback );
+               }
+       }
+} );
+
+jQuery.speed = function( speed, easing, fn ) {
+       var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : {
+               complete: fn || !fn && easing ||
+                       jQuery.isFunction( speed ) && speed,
+               duration: speed,
+               easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing
+       };
+
+       // Go to the end state if fx are off
+       if ( jQuery.fx.off ) {
+               opt.duration = 0;
+
+       } else {
+               if ( typeof opt.duration !== "number" ) {
+                       if ( opt.duration in jQuery.fx.speeds ) {
+                               opt.duration = jQuery.fx.speeds[ opt.duration ];
+
+                       } else {
+                               opt.duration = jQuery.fx.speeds._default;
+                       }
+               }
+       }
+
+       // Normalize opt.queue - true/undefined/null -> "fx"
+       if ( opt.queue == null || opt.queue === true ) {
+               opt.queue = "fx";
+       }
+
+       // Queueing
+       opt.old = opt.complete;
+
+       opt.complete = function() {
+               if ( jQuery.isFunction( opt.old ) ) {
+                       opt.old.call( this );
+               }
+
+               if ( opt.queue ) {
+                       jQuery.dequeue( this, opt.queue );
+               }
+       };
+
+       return opt;
+};
+
+jQuery.fn.extend( {
+       fadeTo: function( speed, to, easing, callback ) {
+
+               // Show any hidden elements after setting opacity to 0
+               return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show()
+
+                       // Animate to the value specified
+                       .end().animate( { opacity: to }, speed, easing, callback );
+       },
+       animate: function( prop, speed, easing, callback ) {
+               var empty = jQuery.isEmptyObject( prop ),
+                       optall = jQuery.speed( speed, easing, callback ),
+                       doAnimation = function() {
+
+                               // Operate on a copy of prop so per-property easing won't be lost
+                               var anim = Animation( this, jQuery.extend( {}, prop ), optall );
+
+                               // Empty animations, or finishing resolves immediately
+                               if ( empty || dataPriv.get( this, "finish" ) ) {
+                                       anim.stop( true );
+                               }
+                       };
+                       doAnimation.finish = doAnimation;
+
+               return empty || optall.queue === false ?
+                       this.each( doAnimation ) :
+                       this.queue( optall.queue, doAnimation );
+       },
+       stop: function( type, clearQueue, gotoEnd ) {
+               var stopQueue = function( hooks ) {
+                       var stop = hooks.stop;
+                       delete hooks.stop;
+                       stop( gotoEnd );
+               };
+
+               if ( typeof type !== "string" ) {
+                       gotoEnd = clearQueue;
+                       clearQueue = type;
+                       type = undefined;
+               }
+               if ( clearQueue && type !== false ) {
+                       this.queue( type || "fx", [] );
+               }
+
+               return this.each( function() {
+                       var dequeue = true,
+                               index = type != null && type + "queueHooks",
+                               timers = jQuery.timers,
+                               data = dataPriv.get( this );
+
+                       if ( index ) {
+                               if ( data[ index ] && data[ index ].stop ) {
+                                       stopQueue( data[ index ] );
+                               }
+                       } else {
+                               for ( index in data ) {
+                                       if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) {
+                                               stopQueue( data[ index ] );
+                                       }
+                               }
+                       }
+
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this &&
+                                       ( type == null || timers[ index ].queue === type ) ) {
+
+                                       timers[ index ].anim.stop( gotoEnd );
+                                       dequeue = false;
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // Start the next in the queue if the last step wasn't forced.
+                       // Timers currently will call their complete callbacks, which
+                       // will dequeue but only if they were gotoEnd.
+                       if ( dequeue || !gotoEnd ) {
+                               jQuery.dequeue( this, type );
+                       }
+               } );
+       },
+       finish: function( type ) {
+               if ( type !== false ) {
+                       type = type || "fx";
+               }
+               return this.each( function() {
+                       var index,
+                               data = dataPriv.get( this ),
+                               queue = data[ type + "queue" ],
+                               hooks = data[ type + "queueHooks" ],
+                               timers = jQuery.timers,
+                               length = queue ? queue.length : 0;
+
+                       // Enable finishing flag on private data
+                       data.finish = true;
+
+                       // Empty the queue first
+                       jQuery.queue( this, type, [] );
+
+                       if ( hooks && hooks.stop ) {
+                               hooks.stop.call( this, true );
+                       }
+
+                       // Look for any active animations, and finish them
+                       for ( index = timers.length; index--; ) {
+                               if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+                                       timers[ index ].anim.stop( true );
+                                       timers.splice( index, 1 );
+                               }
+                       }
+
+                       // Look for any animations in the old queue and finish them
+                       for ( index = 0; index < length; index++ ) {
+                               if ( queue[ index ] && queue[ index ].finish ) {
+                                       queue[ index ].finish.call( this );
+                               }
+                       }
+
+                       // Turn off finishing flag
+                       delete data.finish;
+               } );
+       }
+} );
+
+jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) {
+       var cssFn = jQuery.fn[ name ];
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return speed == null || typeof speed === "boolean" ?
+                       cssFn.apply( this, arguments ) :
+                       this.animate( genFx( name, true ), speed, easing, callback );
+       };
+} );
+
+// Generate shortcuts for custom animations
+jQuery.each( {
+       slideDown: genFx( "show" ),
+       slideUp: genFx( "hide" ),
+       slideToggle: genFx( "toggle" ),
+       fadeIn: { opacity: "show" },
+       fadeOut: { opacity: "hide" },
+       fadeToggle: { opacity: "toggle" }
+}, function( name, props ) {
+       jQuery.fn[ name ] = function( speed, easing, callback ) {
+               return this.animate( props, speed, easing, callback );
+       };
+} );
+
+jQuery.timers = [];
+jQuery.fx.tick = function() {
+       var timer,
+               i = 0,
+               timers = jQuery.timers;
+
+       fxNow = jQuery.now();
+
+       for ( ; i < timers.length; i++ ) {
+               timer = timers[ i ];
+
+               // Run the timer and safely remove it when done (allowing for external removal)
+               if ( !timer() && timers[ i ] === timer ) {
+                       timers.splice( i--, 1 );
+               }
+       }
+
+       if ( !timers.length ) {
+               jQuery.fx.stop();
+       }
+       fxNow = undefined;
+};
+
+jQuery.fx.timer = function( timer ) {
+       jQuery.timers.push( timer );
+       jQuery.fx.start();
+};
+
+jQuery.fx.interval = 13;
+jQuery.fx.start = function() {
+       if ( inProgress ) {
+               return;
+       }
+
+       inProgress = true;
+       schedule();
+};
+
+jQuery.fx.stop = function() {
+       inProgress = null;
+};
+
+jQuery.fx.speeds = {
+       slow: 600,
+       fast: 200,
+
+       // Default speed
+       _default: 400
+};
+
+
+// Based off of the plugin by Clint Helfers, with permission.
+// https://web.archive.org/web/20100324014747/http://blindsignals.com/index.php/2009/07/jquery-delay/
+jQuery.fn.delay = function( time, type ) {
+       time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time;
+       type = type || "fx";
+
+       return this.queue( type, function( next, hooks ) {
+               var timeout = window.setTimeout( next, time );
+               hooks.stop = function() {
+                       window.clearTimeout( timeout );
+               };
+       } );
+};
+
+
+( function() {
+       var input = document.createElement( "input" ),
+               select = document.createElement( "select" ),
+               opt = select.appendChild( document.createElement( "option" ) );
+
+       input.type = "checkbox";
+
+       // Support: Android <=4.3 only
+       // Default value for a checkbox should be "on"
+       support.checkOn = input.value !== "";
+
+       // Support: IE <=11 only
+       // Must access selectedIndex to make default options select
+       support.optSelected = opt.selected;
+
+       // Support: IE <=11 only
+       // An input loses its value after becoming a radio
+       input = document.createElement( "input" );
+       input.value = "t";
+       input.type = "radio";
+       support.radioValue = input.value === "t";
+} )();
+
+
+var boolHook,
+       attrHandle = jQuery.expr.attrHandle;
+
+jQuery.fn.extend( {
+       attr: function( name, value ) {
+               return access( this, jQuery.attr, name, value, arguments.length > 1 );
+       },
+
+       removeAttr: function( name ) {
+               return this.each( function() {
+                       jQuery.removeAttr( this, name );
+               } );
+       }
+} );
+
+jQuery.extend( {
+       attr: function( elem, name, value ) {
+               var ret, hooks,
+                       nType = elem.nodeType;
+
+               // Don't get/set attributes on text, comment and attribute nodes
+               if ( nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               // Fallback to prop when attributes are not supported
+               if ( typeof elem.getAttribute === "undefined" ) {
+                       return jQuery.prop( elem, name, value );
+               }
+
+               // Attribute hooks are determined by the lowercase version
+               // Grab necessary hook if one is defined
+               if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+                       hooks = jQuery.attrHooks[ name.toLowerCase() ] ||
+                               ( jQuery.expr.match.bool.test( name ) ? boolHook : undefined );
+               }
+
+               if ( value !== undefined ) {
+                       if ( value === null ) {
+                               jQuery.removeAttr( elem, name );
+                               return;
+                       }
+
+                       if ( hooks && "set" in hooks &&
+                               ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+                               return ret;
+                       }
+
+                       elem.setAttribute( name, value + "" );
+                       return value;
+               }
+
+               if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+                       return ret;
+               }
+
+               ret = jQuery.find.attr( elem, name );
+
+               // Non-existent attributes return null, we normalize to undefined
+               return ret == null ? undefined : ret;
+       },
+
+       attrHooks: {
+               type: {
+                       set: function( elem, value ) {
+                               if ( !support.radioValue && value === "radio" &&
+                                       nodeName( elem, "input" ) ) {
+                                       var val = elem.value;
+                                       elem.setAttribute( "type", value );
+                                       if ( val ) {
+                                               elem.value = val;
+                                       }
+                                       return value;
+                               }
+                       }
+               }
+       },
+
+       removeAttr: function( elem, value ) {
+               var name,
+                       i = 0,
+
+                       // Attribute names can contain non-HTML whitespace characters
+                       // https://html.spec.whatwg.org/multipage/syntax.html#attributes-2
+                       attrNames = value && value.match( rnothtmlwhite );
+
+               if ( attrNames && elem.nodeType === 1 ) {
+                       while ( ( name = attrNames[ i++ ] ) ) {
+                               elem.removeAttribute( name );
+                       }
+               }
+       }
+} );
+
+// Hooks for boolean attributes
+boolHook = {
+       set: function( elem, value, name ) {
+               if ( value === false ) {
+
+                       // Remove boolean attributes when set to false
+                       jQuery.removeAttr( elem, name );
+               } else {
+                       elem.setAttribute( name, name );
+               }
+               return name;
+       }
+};
+
+jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
+       var getter = attrHandle[ name ] || jQuery.find.attr;
+
+       attrHandle[ name ] = function( elem, name, isXML ) {
+               var ret, handle,
+                       lowercaseName = name.toLowerCase();
+
+               if ( !isXML ) {
+
+                       // Avoid an infinite loop by temporarily removing this function from the getter
+                       handle = attrHandle[ lowercaseName ];
+                       attrHandle[ lowercaseName ] = ret;
+                       ret = getter( elem, name, isXML ) != null ?
+                               lowercaseName :
+                               null;
+                       attrHandle[ lowercaseName ] = handle;
+               }
+               return ret;
+       };
+} );
+
+
+
+
+var rfocusable = /^(?:input|select|textarea|button)$/i,
+       rclickable = /^(?:a|area)$/i;
+
+jQuery.fn.extend( {
+       prop: function( name, value ) {
+               return access( this, jQuery.prop, name, value, arguments.length > 1 );
+       },
+
+       removeProp: function( name ) {
+               return this.each( function() {
+                       delete this[ jQuery.propFix[ name ] || name ];
+               } );
+       }
+} );
+
+jQuery.extend( {
+       prop: function( elem, name, value ) {
+               var ret, hooks,
+                       nType = elem.nodeType;
+
+               // Don't get/set properties on text, comment and attribute nodes
+               if ( nType === 3 || nType === 8 || nType === 2 ) {
+                       return;
+               }
+
+               if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
+
+                       // Fix name and attach hooks
+                       name = jQuery.propFix[ name ] || name;
+                       hooks = jQuery.propHooks[ name ];
+               }
+
+               if ( value !== undefined ) {
+                       if ( hooks && "set" in hooks &&
+                               ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
+                               return ret;
+                       }
+
+                       return ( elem[ name ] = value );
+               }
+
+               if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
+                       return ret;
+               }
+
+               return elem[ name ];
+       },
+
+       propHooks: {
+               tabIndex: {
+                       get: function( elem ) {
+
+                               // Support: IE <=9 - 11 only
+                               // elem.tabIndex doesn't always return the
+                               // correct value when it hasn't been explicitly set
+                               // 
https://web.archive.org/web/20141116233347/http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
+                               // Use proper attribute retrieval(#12072)
+                               var tabindex = jQuery.find.attr( elem, "tabindex" );
+
+                               if ( tabindex ) {
+                                       return parseInt( tabindex, 10 );
+                               }
+
+                               if (
+                                       rfocusable.test( elem.nodeName ) ||
+                                       rclickable.test( elem.nodeName ) &&
+                                       elem.href
+                               ) {
+                                       return 0;
+                               }
+
+                               return -1;
+                       }
+               }
+       },
+
+       propFix: {
+               "for": "htmlFor",
+               "class": "className"
+       }
+} );
+
+// Support: IE <=11 only
+// Accessing the selectedIndex property
+// forces the browser to respect setting selected
+// on the option
+// The getter ensures a default option is selected
+// when in an optgroup
+// eslint rule "no-unused-expressions" is disabled for this code
+// since it considers such accessions noop
+if ( !support.optSelected ) {
+       jQuery.propHooks.selected = {
+               get: function( elem ) {
+
+                       /* eslint no-unused-expressions: "off" */
+
+                       var parent = elem.parentNode;
+                       if ( parent && parent.parentNode ) {
+                               parent.parentNode.selectedIndex;
+                       }
+                       return null;
+               },
+               set: function( elem ) {
+
+                       /* eslint no-unused-expressions: "off" */
+
+                       var parent = elem.parentNode;
+                       if ( parent ) {
+                               parent.selectedIndex;
+
+                               if ( parent.parentNode ) {
+                                       parent.parentNode.selectedIndex;
+                               }
+                       }
+               }
+       };
+}
+
+jQuery.each( [
+       "tabIndex",
+       "readOnly",
+       "maxLength",
+       "cellSpacing",
+       "cellPadding",
+       "rowSpan",
+       "colSpan",
+       "useMap",
+       "frameBorder",
+       "contentEditable"
+], function() {
+       jQuery.propFix[ this.toLowerCase() ] = this;
+} );
+
+
+
+
+       // Strip and collapse whitespace according to HTML spec
+       // https://html.spec.whatwg.org/multipage/infrastructure.html#strip-and-collapse-whitespace
+       function stripAndCollapse( value ) {
+               var tokens = value.match( rnothtmlwhite ) || [];
+               return tokens.join( " " );
+       }
+
+
+function getClass( elem ) {
+       return elem.getAttribute && elem.getAttribute( "class" ) || "";
+}
+
+jQuery.fn.extend( {
+       addClass: function( value ) {
+               var classes, elem, cur, curValue, clazz, j, finalValue,
+                       i = 0;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each( function( j ) {
+                               jQuery( this ).addClass( value.call( this, j, getClass( this ) ) );
+                       } );
+               }
+
+               if ( typeof value === "string" && value ) {
+                       classes = value.match( rnothtmlwhite ) || [];
+
+                       while ( ( elem = this[ i++ ] ) ) {
+                               curValue = getClass( elem );
+                               cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( ( clazz = classes[ j++ ] ) ) {
+                                               if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+                                                       cur += clazz + " ";
+                                               }
+                                       }
+
+                                       // Only assign if different to avoid unneeded rendering.
+                                       finalValue = stripAndCollapse( cur );
+                                       if ( curValue !== finalValue ) {
+                                               elem.setAttribute( "class", finalValue );
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       removeClass: function( value ) {
+               var classes, elem, cur, curValue, clazz, j, finalValue,
+                       i = 0;
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each( function( j ) {
+                               jQuery( this ).removeClass( value.call( this, j, getClass( this ) ) );
+                       } );
+               }
+
+               if ( !arguments.length ) {
+                       return this.attr( "class", "" );
+               }
+
+               if ( typeof value === "string" && value ) {
+                       classes = value.match( rnothtmlwhite ) || [];
+
+                       while ( ( elem = this[ i++ ] ) ) {
+                               curValue = getClass( elem );
+
+                               // This expression is here for better compressibility (see addClass)
+                               cur = elem.nodeType === 1 && ( " " + stripAndCollapse( curValue ) + " " );
+
+                               if ( cur ) {
+                                       j = 0;
+                                       while ( ( clazz = classes[ j++ ] ) ) {
+
+                                               // Remove *all* instances
+                                               while ( cur.indexOf( " " + clazz + " " ) > -1 ) {
+                                                       cur = cur.replace( " " + clazz + " ", " " );
+                                               }
+                                       }
+
+                                       // Only assign if different to avoid unneeded rendering.
+                                       finalValue = stripAndCollapse( cur );
+                                       if ( curValue !== finalValue ) {
+                                               elem.setAttribute( "class", finalValue );
+                                       }
+                               }
+                       }
+               }
+
+               return this;
+       },
+
+       toggleClass: function( value, stateVal ) {
+               var type = typeof value;
+
+               if ( typeof stateVal === "boolean" && type === "string" ) {
+                       return stateVal ? this.addClass( value ) : this.removeClass( value );
+               }
+
+               if ( jQuery.isFunction( value ) ) {
+                       return this.each( function( i ) {
+                               jQuery( this ).toggleClass(
+                                       value.call( this, i, getClass( this ), stateVal ),
+                                       stateVal
+                               );
+                       } );
+               }
+
+               return this.each( function() {
+                       var className, i, self, classNames;
+
+                       if ( type === "string" ) {
+
+                               // Toggle individual class names
+                               i = 0;
+                               self = jQuery( this );
+                               classNames = value.match( rnothtmlwhite ) || [];
+
+                               while ( ( className = classNames[ i++ ] ) ) {
+
+                                       // Check each className given, space separated list
+                                       if ( self.hasClass( className ) ) {
+                                               self.removeClass( className );
+                                       } else {
+                                               self.addClass( className );
+                                       }
+                               }
+
+                       // Toggle whole class name
+                       } else if ( value === undefined || type === "boolean" ) {
+                               className = getClass( this );
+                               if ( className ) {
+
+                                       // Store className if set
+                                       dataPriv.set( this, "__className__", className );
+                               }
+
+                               // If the element has a class name or if we're passed `false`,
+                               // then remove the whole classname (if there was one, the above saved it).
+                               // Otherwise bring back whatever was previously saved (if anything),
+                               // falling back to the empty string if nothing was stored.
+                               if ( this.setAttribute ) {
+                                       this.setAttribute( "class",
+                                               className || value === false ?
+                                               "" :
+                                               dataPriv.get( this, "__className__" ) || ""
+                                       );
+                               }
+                       }
+               } );
+       },
+
+       hasClass: function( selector ) {
+               var className, elem,
+                       i = 0;
+
+               className = " " + selector + " ";
+               while ( ( elem = this[ i++ ] ) ) {
+                       if ( elem.nodeType === 1 &&
+                               ( " " + stripAndCollapse( getClass( elem ) ) + " " ).indexOf( className ) > 
-1 ) {
+                                       return true;
+                       }
+               }
+
+               return false;
+       }
+} );
+
+
+
+
+var rreturn = /\r/g;
+
+jQuery.fn.extend( {
+       val: function( value ) {
+               var hooks, ret, isFunction,
+                       elem = this[ 0 ];
+
+               if ( !arguments.length ) {
+                       if ( elem ) {
+                               hooks = jQuery.valHooks[ elem.type ] ||
+                                       jQuery.valHooks[ elem.nodeName.toLowerCase() ];
+
+                               if ( hooks &&
+                                       "get" in hooks &&
+                                       ( ret = hooks.get( elem, "value" ) ) !== undefined
+                               ) {
+                                       return ret;
+                               }
+
+                               ret = elem.value;
+
+                               // Handle most common string cases
+                               if ( typeof ret === "string" ) {
+                                       return ret.replace( rreturn, "" );
+                               }
+
+                               // Handle cases where value is null/undef or number
+                               return ret == null ? "" : ret;
+                       }
+
+                       return;
+               }
+
+               isFunction = jQuery.isFunction( value );
+
+               return this.each( function( i ) {
+                       var val;
+
+                       if ( this.nodeType !== 1 ) {
+                               return;
+                       }
+
+                       if ( isFunction ) {
+                               val = value.call( this, i, jQuery( this ).val() );
+                       } else {
+                               val = value;
+                       }
+
+                       // Treat null/undefined as ""; convert numbers to string
+                       if ( val == null ) {
+                               val = "";
+
+                       } else if ( typeof val === "number" ) {
+                               val += "";
+
+                       } else if ( Array.isArray( val ) ) {
+                               val = jQuery.map( val, function( value ) {
+                                       return value == null ? "" : value + "";
+                               } );
+                       }
+
+                       hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() 
];
+
+                       // If set returns undefined, fall back to normal setting
+                       if ( !hooks || !( "set" in hooks ) || hooks.set( this, val, "value" ) === undefined ) 
{
+                               this.value = val;
+                       }
+               } );
+       }
+} );
+
+jQuery.extend( {
+       valHooks: {
+               option: {
+                       get: function( elem ) {
+
+                               var val = jQuery.find.attr( elem, "value" );
+                               return val != null ?
+                                       val :
+
+                                       // Support: IE <=10 - 11 only
+                                       // option.text throws exceptions (#14686, #14858)
+                                       // Strip and collapse whitespace
+                                       // https://html.spec.whatwg.org/#strip-and-collapse-whitespace
+                                       stripAndCollapse( jQuery.text( elem ) );
+                       }
+               },
+               select: {
+                       get: function( elem ) {
+                               var value, option, i,
+                                       options = elem.options,
+                                       index = elem.selectedIndex,
+                                       one = elem.type === "select-one",
+                                       values = one ? null : [],
+                                       max = one ? index + 1 : options.length;
+
+                               if ( index < 0 ) {
+                                       i = max;
+
+                               } else {
+                                       i = one ? index : 0;
+                               }
+
+                               // Loop through all the selected options
+                               for ( ; i < max; i++ ) {
+                                       option = options[ i ];
+
+                                       // Support: IE <=9 only
+                                       // IE8-9 doesn't update selected after form reset (#2551)
+                                       if ( ( option.selected || i === index ) &&
+
+                                                       // Don't return options that are disabled or in a 
disabled optgroup
+                                                       !option.disabled &&
+                                                       ( !option.parentNode.disabled ||
+                                                               !nodeName( option.parentNode, "optgroup" ) ) 
) {
+
+                                               // Get the specific value for the option
+                                               value = jQuery( option ).val();
+
+                                               // We don't need an array for one selects
+                                               if ( one ) {
+                                                       return value;
+                                               }
+
+                                               // Multi-Selects return an array
+                                               values.push( value );
+                                       }
+                               }
+
+                               return values;
+                       },
+
+                       set: function( elem, value ) {
+                               var optionSet, option,
+                                       options = elem.options,
+                                       values = jQuery.makeArray( value ),
+                                       i = options.length;
+
+                               while ( i-- ) {
+                                       option = options[ i ];
+
+                                       /* eslint-disable no-cond-assign */
+
+                                       if ( option.selected =
+                                               jQuery.inArray( jQuery.valHooks.option.get( option ), values 
) > -1
+                                       ) {
+                                               optionSet = true;
+                                       }
+
+                                       /* eslint-enable no-cond-assign */
+                               }
+
+                               // Force browsers to behave consistently when non-matching value is set
+                               if ( !optionSet ) {
+                                       elem.selectedIndex = -1;
+                               }
+                               return values;
+                       }
+               }
+       }
+} );
+
+// Radios and checkboxes getter/setter
+jQuery.each( [ "radio", "checkbox" ], function() {
+       jQuery.valHooks[ this ] = {
+               set: function( elem, value ) {
+                       if ( Array.isArray( value ) ) {
+                               return ( elem.checked = jQuery.inArray( jQuery( elem ).val(), value ) > -1 );
+                       }
+               }
+       };
+       if ( !support.checkOn ) {
+               jQuery.valHooks[ this ].get = function( elem ) {
+                       return elem.getAttribute( "value" ) === null ? "on" : elem.value;
+               };
+       }
+} );
+
+
+
+
+// Return jQuery for attributes-only inclusion
+
+
+var rfocusMorph = /^(?:focusinfocus|focusoutblur)$/;
+
+jQuery.extend( jQuery.event, {
+
+       trigger: function( event, data, elem, onlyHandlers ) {
+
+               var i, cur, tmp, bubbleType, ontype, handle, special,
+                       eventPath = [ elem || document ],
+                       type = hasOwn.call( event, "type" ) ? event.type : event,
+                       namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
+
+               cur = tmp = elem = elem || document;
+
+               // Don't do events on text and comment nodes
+               if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+                       return;
+               }
+
+               // focus/blur morphs to focusin/out; ensure we're not firing them right now
+               if ( rfocusMorph.test( type + jQuery.event.triggered ) ) {
+                       return;
+               }
+
+               if ( type.indexOf( "." ) > -1 ) {
+
+                       // Namespaced trigger; create a regexp to match event type in handle()
+                       namespaces = type.split( "." );
+                       type = namespaces.shift();
+                       namespaces.sort();
+               }
+               ontype = type.indexOf( ":" ) < 0 && "on" + type;
+
+               // Caller can pass in a jQuery.Event object, Object, or just an event type string
+               event = event[ jQuery.expando ] ?
+                       event :
+                       new jQuery.Event( type, typeof event === "object" && event );
+
+               // Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
+               event.isTrigger = onlyHandlers ? 2 : 3;
+               event.namespace = namespaces.join( "." );
+               event.rnamespace = event.namespace ?
+                       new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
+                       null;
+
+               // Clean up the event in case it is being reused
+               event.result = undefined;
+               if ( !event.target ) {
+                       event.target = elem;
+               }
+
+               // Clone any incoming data and prepend the event, creating the handler arg list
+               data = data == null ?
+                       [ event ] :
+                       jQuery.makeArray( data, [ event ] );
+
+               // Allow special events to draw outside the lines
+               special = jQuery.event.special[ type ] || {};
+               if ( !onlyHandlers && special.trigger && special.trigger.apply( elem, data ) === false ) {
+                       return;
+               }
+
+               // Determine event propagation path in advance, per W3C events spec (#9951)
+               // Bubble up to document, then to window; watch for a global ownerDocument var (#9724)
+               if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+                       bubbleType = special.delegateType || type;
+                       if ( !rfocusMorph.test( bubbleType + type ) ) {
+                               cur = cur.parentNode;
+                       }
+                       for ( ; cur; cur = cur.parentNode ) {
+                               eventPath.push( cur );
+                               tmp = cur;
+                       }
+
+                       // Only add window if we got to document (e.g., not plain obj or detached DOM)
+                       if ( tmp === ( elem.ownerDocument || document ) ) {
+                               eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+                       }
+               }
+
+               // Fire handlers on the event path
+               i = 0;
+               while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
+
+                       event.type = i > 1 ?
+                               bubbleType :
+                               special.bindType || type;
+
+                       // jQuery handler
+                       handle = ( dataPriv.get( cur, "events" ) || {} )[ event.type ] &&
+                               dataPriv.get( cur, "handle" );
+                       if ( handle ) {
+                               handle.apply( cur, data );
+                       }
+
+                       // Native handler
+                       handle = ontype && cur[ ontype ];
+                       if ( handle && handle.apply && acceptData( cur ) ) {
+                               event.result = handle.apply( cur, data );
+                               if ( event.result === false ) {
+                                       event.preventDefault();
+                               }
+                       }
+               }
+               event.type = type;
+
+               // If nobody prevented the default action, do it now
+               if ( !onlyHandlers && !event.isDefaultPrevented() ) {
+
+                       if ( ( !special._default ||
+                               special._default.apply( eventPath.pop(), data ) === false ) &&
+                               acceptData( elem ) ) {
+
+                               // Call a native DOM method on the target with the same name as the event.
+                               // Don't do default actions on window, that's where global variables be 
(#6170)
+                               if ( ontype && jQuery.isFunction( elem[ type ] ) && !jQuery.isWindow( elem ) 
) {
+
+                                       // Don't re-trigger an onFOO event when we call its FOO() method
+                                       tmp = elem[ ontype ];
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = null;
+                                       }
+
+                                       // Prevent re-triggering of the same event, since we already bubbled 
it above
+                                       jQuery.event.triggered = type;
+                                       elem[ type ]();
+                                       jQuery.event.triggered = undefined;
+
+                                       if ( tmp ) {
+                                               elem[ ontype ] = tmp;
+                                       }
+                               }
+                       }
+               }
+
+               return event.result;
+       },
+
+       // Piggyback on a donor event to simulate a different one
+       // Used only for `focus(in | out)` events
+       simulate: function( type, elem, event ) {
+               var e = jQuery.extend(
+                       new jQuery.Event(),
+                       event,
+                       {
+                               type: type,
+                               isSimulated: true
+                       }
+               );
+
+               jQuery.event.trigger( e, null, elem );
+       }
+
+} );
+
+jQuery.fn.extend( {
+
+       trigger: function( type, data ) {
+               return this.each( function() {
+                       jQuery.event.trigger( type, data, this );
+               } );
+       },
+       triggerHandler: function( type, data ) {
+               var elem = this[ 0 ];
+               if ( elem ) {
+                       return jQuery.event.trigger( type, data, elem, true );
+               }
+       }
+} );
+
+
+jQuery.each( ( "blur focus focusin focusout resize scroll click dblclick " +
+       "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
+       "change select submit keydown keypress keyup contextmenu" ).split( " " ),
+       function( i, name ) {
+
+       // Handle event binding
+       jQuery.fn[ name ] = function( data, fn ) {
+               return arguments.length > 0 ?
+                       this.on( name, null, data, fn ) :
+                       this.trigger( name );
+       };
+} );
+
+jQuery.fn.extend( {
+       hover: function( fnOver, fnOut ) {
+               return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+       }
+} );
+
+
+
+
+support.focusin = "onfocusin" in window;
+
+
+// Support: Firefox <=44
+// Firefox doesn't have focus(in | out) events
+// Related ticket - https://bugzilla.mozilla.org/show_bug.cgi?id=687787
+//
+// Support: Chrome <=48 - 49, Safari <=9.0 - 9.1
+// focus(in | out) events fire after focus & blur events,
+// which is spec violation - http://www.w3.org/TR/DOM-Level-3-Events/#events-focusevent-event-order
+// Related ticket - https://bugs.chromium.org/p/chromium/issues/detail?id=449857
+if ( !support.focusin ) {
+       jQuery.each( { focus: "focusin", blur: "focusout" }, function( orig, fix ) {
+
+               // Attach a single capturing handler on the document while someone wants focusin/focusout
+               var handler = function( event ) {
+                       jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ) );
+               };
+
+               jQuery.event.special[ fix ] = {
+                       setup: function() {
+                               var doc = this.ownerDocument || this,
+                                       attaches = dataPriv.access( doc, fix );
+
+                               if ( !attaches ) {
+                                       doc.addEventListener( orig, handler, true );
+                               }
+                               dataPriv.access( doc, fix, ( attaches || 0 ) + 1 );
+                       },
+                       teardown: function() {
+                               var doc = this.ownerDocument || this,
+                                       attaches = dataPriv.access( doc, fix ) - 1;
+
+                               if ( !attaches ) {
+                                       doc.removeEventListener( orig, handler, true );
+                                       dataPriv.remove( doc, fix );
+
+                               } else {
+                                       dataPriv.access( doc, fix, attaches );
+                               }
+                       }
+               };
+       } );
+}
+var location = window.location;
+
+var nonce = jQuery.now();
+
+var rquery = ( /\?/ );
+
+
+
+// Cross-browser xml parsing
+jQuery.parseXML = function( data ) {
+       var xml;
+       if ( !data || typeof data !== "string" ) {
+               return null;
+       }
+
+       // Support: IE 9 - 11 only
+       // IE throws on parseFromString with invalid input.
+       try {
+               xml = ( new window.DOMParser() ).parseFromString( data, "text/xml" );
+       } catch ( e ) {
+               xml = undefined;
+       }
+
+       if ( !xml || xml.getElementsByTagName( "parsererror" ).length ) {
+               jQuery.error( "Invalid XML: " + data );
+       }
+       return xml;
+};
+
+
+var
+       rbracket = /\[\]$/,
+       rCRLF = /\r?\n/g,
+       rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+       rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+function buildParams( prefix, obj, traditional, add ) {
+       var name;
+
+       if ( Array.isArray( obj ) ) {
+
+               // Serialize array item.
+               jQuery.each( obj, function( i, v ) {
+                       if ( traditional || rbracket.test( prefix ) ) {
+
+                               // Treat each array item as a scalar.
+                               add( prefix, v );
+
+                       } else {
+
+                               // Item is non-scalar (array or object), encode its numeric index.
+                               buildParams(
+                                       prefix + "[" + ( typeof v === "object" && v != null ? i : "" ) + "]",
+                                       v,
+                                       traditional,
+                                       add
+                               );
+                       }
+               } );
+
+       } else if ( !traditional && jQuery.type( obj ) === "object" ) {
+
+               // Serialize object item.
+               for ( name in obj ) {
+                       buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add );
+               }
+
+       } else {
+
+               // Serialize scalar item.
+               add( prefix, obj );
+       }
+}
+
+// Serialize an array of form elements or a set of
+// key/values into a query string
+jQuery.param = function( a, traditional ) {
+       var prefix,
+               s = [],
+               add = function( key, valueOrFunction ) {
+
+                       // If value is a function, invoke it and use its return value
+                       var value = jQuery.isFunction( valueOrFunction ) ?
+                               valueOrFunction() :
+                               valueOrFunction;
+
+                       s[ s.length ] = encodeURIComponent( key ) + "=" +
+                               encodeURIComponent( value == null ? "" : value );
+               };
+
+       // If an array was passed in, assume that it is an array of form elements.
+       if ( Array.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) {
+
+               // Serialize the form elements
+               jQuery.each( a, function() {
+                       add( this.name, this.value );
+               } );
+
+       } else {
+
+               // If traditional, encode the "old" way (the way 1.3.2 or older
+               // did it), otherwise encode params recursively.
+               for ( prefix in a ) {
+                       buildParams( prefix, a[ prefix ], traditional, add );
+               }
+       }
+
+       // Return the resulting serialization
+       return s.join( "&" );
+};
+
+jQuery.fn.extend( {
+       serialize: function() {
+               return jQuery.param( this.serializeArray() );
+       },
+       serializeArray: function() {
+               return this.map( function() {
+
+                       // Can add propHook for "elements" to filter or add form elements
+                       var elements = jQuery.prop( this, "elements" );
+                       return elements ? jQuery.makeArray( elements ) : this;
+               } )
+               .filter( function() {
+                       var type = this.type;
+
+                       // Use .is( ":disabled" ) so that fieldset[disabled] works
+                       return this.name && !jQuery( this ).is( ":disabled" ) &&
+                               rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+                               ( this.checked || !rcheckableType.test( type ) );
+               } )
+               .map( function( i, elem ) {
+                       var val = jQuery( this ).val();
+
+                       if ( val == null ) {
+                               return null;
+                       }
+
+                       if ( Array.isArray( val ) ) {
+                               return jQuery.map( val, function( val ) {
+                                       return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+                               } );
+                       }
+
+                       return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) };
+               } ).get();
+       }
+} );
+
+
+var
+       r20 = /%20/g,
+       rhash = /#.*$/,
+       rantiCache = /([?&])_=[^&]*/,
+       rheaders = /^(.*?):[ \t]*([^\r\n]*)$/mg,
+
+       // #7653, #8125, #8152: local protocol detection
+       rlocalProtocol = /^(?:about|app|app-storage|.+-extension|file|res|widget):$/,
+       rnoContent = /^(?:GET|HEAD)$/,
+       rprotocol = /^\/\//,
+
+       /* Prefilters
+        * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example)
+        * 2) These are called:
+        *    - BEFORE asking for a transport
+        *    - AFTER param serialization (s.data is a string if s.processData is true)
+        * 3) key is the dataType
+        * 4) the catchall symbol "*" can be used
+        * 5) execution will start with transport dataType and THEN continue down to "*" if needed
+        */
+       prefilters = {},
+
+       /* Transports bindings
+        * 1) key is the dataType
+        * 2) the catchall symbol "*" can be used
+        * 3) selection will start with transport dataType and THEN go to "*" if needed
+        */
+       transports = {},
+
+       // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression
+       allTypes = "*/".concat( "*" ),
+
+       // Anchor tag for parsing the document origin
+       originAnchor = document.createElement( "a" );
+       originAnchor.href = location.href;
+
+// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport
+function addToPrefiltersOrTransports( structure ) {
+
+       // dataTypeExpression is optional and defaults to "*"
+       return function( dataTypeExpression, func ) {
+
+               if ( typeof dataTypeExpression !== "string" ) {
+                       func = dataTypeExpression;
+                       dataTypeExpression = "*";
+               }
+
+               var dataType,
+                       i = 0,
+                       dataTypes = dataTypeExpression.toLowerCase().match( rnothtmlwhite ) || [];
+
+               if ( jQuery.isFunction( func ) ) {
+
+                       // For each dataType in the dataTypeExpression
+                       while ( ( dataType = dataTypes[ i++ ] ) ) {
+
+                               // Prepend if requested
+                               if ( dataType[ 0 ] === "+" ) {
+                                       dataType = dataType.slice( 1 ) || "*";
+                                       ( structure[ dataType ] = structure[ dataType ] || [] ).unshift( func 
);
+
+                               // Otherwise append
+                               } else {
+                                       ( structure[ dataType ] = structure[ dataType ] || [] ).push( func );
+                               }
+                       }
+               }
+       };
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+       var inspected = {},
+               seekingTransport = ( structure === transports );
+
+       function inspect( dataType ) {
+               var selected;
+               inspected[ dataType ] = true;
+               jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+                       var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+                       if ( typeof dataTypeOrTransport === "string" &&
+                               !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+
+                               options.dataTypes.unshift( dataTypeOrTransport );
+                               inspect( dataTypeOrTransport );
+                               return false;
+                       } else if ( seekingTransport ) {
+                               return !( selected = dataTypeOrTransport );
+                       }
+               } );
+               return selected;
+       }
+
+       return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+       var key, deep,
+               flatOptions = jQuery.ajaxSettings.flatOptions || {};
+
+       for ( key in src ) {
+               if ( src[ key ] !== undefined ) {
+                       ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ];
+               }
+       }
+       if ( deep ) {
+               jQuery.extend( true, target, deep );
+       }
+
+       return target;
+}
+
+/* Handles responses to an ajax request:
+ * - finds the right dataType (mediates between content-type and expected dataType)
+ * - returns the corresponding response
+ */
+function ajaxHandleResponses( s, jqXHR, responses ) {
+
+       var ct, type, finalDataType, firstDataType,
+               contents = s.contents,
+               dataTypes = s.dataTypes;
+
+       // Remove auto dataType and get content-type in the process
+       while ( dataTypes[ 0 ] === "*" ) {
+               dataTypes.shift();
+               if ( ct === undefined ) {
+                       ct = s.mimeType || jqXHR.getResponseHeader( "Content-Type" );
+               }
+       }
+
+       // Check if we're dealing with a known content-type
+       if ( ct ) {
+               for ( type in contents ) {
+                       if ( contents[ type ] && contents[ type ].test( ct ) ) {
+                               dataTypes.unshift( type );
+                               break;
+                       }
+               }
+       }
+
+       // Check to see if we have a response for the expected dataType
+       if ( dataTypes[ 0 ] in responses ) {
+               finalDataType = dataTypes[ 0 ];
+       } else {
+
+               // Try convertible dataTypes
+               for ( type in responses ) {
+                       if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[ 0 ] ] ) {
+                               finalDataType = type;
+                               break;
+                       }
+                       if ( !firstDataType ) {
+                               firstDataType = type;
+                       }
+               }
+
+               // Or just use first one
+               finalDataType = finalDataType || firstDataType;
+       }
+
+       // If we found a dataType
+       // We add the dataType to the list if needed
+       // and return the corresponding response
+       if ( finalDataType ) {
+               if ( finalDataType !== dataTypes[ 0 ] ) {
+                       dataTypes.unshift( finalDataType );
+               }
+               return responses[ finalDataType ];
+       }
+}
+
+/* Chain conversions given the request and the original response
+ * Also sets the responseXXX fields on the jqXHR instance
+ */
+function ajaxConvert( s, response, jqXHR, isSuccess ) {
+       var conv2, current, conv, tmp, prev,
+               converters = {},
+
+               // Work with a copy of dataTypes in case we need to modify it for conversion
+               dataTypes = s.dataTypes.slice();
+
+       // Create converters map with lowercased keys
+       if ( dataTypes[ 1 ] ) {
+               for ( conv in s.converters ) {
+                       converters[ conv.toLowerCase() ] = s.converters[ conv ];
+               }
+       }
+
+       current = dataTypes.shift();
+
+       // Convert to each sequential dataType
+       while ( current ) {
+
+               if ( s.responseFields[ current ] ) {
+                       jqXHR[ s.responseFields[ current ] ] = response;
+               }
+
+               // Apply the dataFilter if provided
+               if ( !prev && isSuccess && s.dataFilter ) {
+                       response = s.dataFilter( response, s.dataType );
+               }
+
+               prev = current;
+               current = dataTypes.shift();
+
+               if ( current ) {
+
+                       // There's only work to do if current dataType is non-auto
+                       if ( current === "*" ) {
+
+                               current = prev;
+
+                       // Convert response if prev dataType is non-auto and differs from current
+                       } else if ( prev !== "*" && prev !== current ) {
+
+                               // Seek a direct converter
+                               conv = converters[ prev + " " + current ] || converters[ "* " + current ];
+
+                               // If none found, seek a pair
+                               if ( !conv ) {
+                                       for ( conv2 in converters ) {
+
+                                               // If conv2 outputs current
+                                               tmp = conv2.split( " " );
+                                               if ( tmp[ 1 ] === current ) {
+
+                                                       // If prev can be converted to accepted input
+                                                       conv = converters[ prev + " " + tmp[ 0 ] ] ||
+                                                               converters[ "* " + tmp[ 0 ] ];
+                                                       if ( conv ) {
+
+                                                               // Condense equivalence converters
+                                                               if ( conv === true ) {
+                                                                       conv = converters[ conv2 ];
+
+                                                               // Otherwise, insert the intermediate dataType
+                                                               } else if ( converters[ conv2 ] !== true ) {
+                                                                       current = tmp[ 0 ];
+                                                                       dataTypes.unshift( tmp[ 1 ] );
+                                                               }
+                                                               break;
+                                                       }
+                                               }
+                                       }
+                               }
+
+                               // Apply converter (if not an equivalence)
+                               if ( conv !== true ) {
+
+                                       // Unless errors are allowed to bubble, catch and return them
+                                       if ( conv && s.throws ) {
+                                               response = conv( response );
+                                       } else {
+                                               try {
+                                                       response = conv( response );
+                                               } catch ( e ) {
+                                                       return {
+                                                               state: "parsererror",
+                                                               error: conv ? e : "No conversion from " + 
prev + " to " + current
+                                                       };
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       return { state: "success", data: response };
+}
+
+jQuery.extend( {
+
+       // Counter for holding the number of active queries
+       active: 0,
+
+       // Last-Modified header cache for next request
+       lastModified: {},
+       etag: {},
+
+       ajaxSettings: {
+               url: location.href,
+               type: "GET",
+               isLocal: rlocalProtocol.test( location.protocol ),
+               global: true,
+               processData: true,
+               async: true,
+               contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+
+               /*
+               timeout: 0,
+               data: null,
+               dataType: null,
+               username: null,
+               password: null,
+               cache: null,
+               throws: false,
+               traditional: false,
+               headers: {},
+               */
+
+               accepts: {
+                       "*": allTypes,
+                       text: "text/plain",
+                       html: "text/html",
+                       xml: "application/xml, text/xml",
+                       json: "application/json, text/javascript"
+               },
+
+               contents: {
+                       xml: /\bxml\b/,
+                       html: /\bhtml/,
+                       json: /\bjson\b/
+               },
+
+               responseFields: {
+                       xml: "responseXML",
+                       text: "responseText",
+                       json: "responseJSON"
+               },
+
+               // Data converters
+               // Keys separate source (or catchall "*") and destination types with a single space
+               converters: {
+
+                       // Convert anything to text
+                       "* text": String,
+
+                       // Text to html (true = no transformation)
+                       "text html": true,
+
+                       // Evaluate text as a json expression
+                       "text json": JSON.parse,
+
+                       // Parse text as xml
+                       "text xml": jQuery.parseXML
+               },
+
+               // For options that shouldn't be deep extended:
+               // you can add your own custom options here if
+               // and when you create one that shouldn't be
+               // deep extended (see ajaxExtend)
+               flatOptions: {
+                       url: true,
+                       context: true
+               }
+       },
+
+       // Creates a full fledged settings object into target
+       // with both ajaxSettings and settings fields.
+       // If target is omitted, writes into ajaxSettings.
+       ajaxSetup: function( target, settings ) {
+               return settings ?
+
+                       // Building a settings object
+                       ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+                       // Extending ajaxSettings
+                       ajaxExtend( jQuery.ajaxSettings, target );
+       },
+
+       ajaxPrefilter: addToPrefiltersOrTransports( prefilters ),
+       ajaxTransport: addToPrefiltersOrTransports( transports ),
+
+       // Main method
+       ajax: function( url, options ) {
+
+               // If url is an object, simulate pre-1.5 signature
+               if ( typeof url === "object" ) {
+                       options = url;
+                       url = undefined;
+               }
+
+               // Force options to be an object
+               options = options || {};
+
+               var transport,
+
+                       // URL without anti-cache param
+                       cacheURL,
+
+                       // Response headers
+                       responseHeadersString,
+                       responseHeaders,
+
+                       // timeout handle
+                       timeoutTimer,
+
+                       // Url cleanup var
+                       urlAnchor,
+
+                       // Request state (becomes false upon send and true upon completion)
+                       completed,
+
+                       // To know if global events are to be dispatched
+                       fireGlobals,
+
+                       // Loop variable
+                       i,
+
+                       // uncached part of the url
+                       uncached,
+
+                       // Create the final options object
+                       s = jQuery.ajaxSetup( {}, options ),
+
+                       // Callbacks context
+                       callbackContext = s.context || s,
+
+                       // Context for global events is callbackContext if it is a DOM node or jQuery 
collection
+                       globalEventContext = s.context &&
+                               ( callbackContext.nodeType || callbackContext.jquery ) ?
+                                       jQuery( callbackContext ) :
+                                       jQuery.event,
+
+                       // Deferreds
+                       deferred = jQuery.Deferred(),
+                       completeDeferred = jQuery.Callbacks( "once memory" ),
+
+                       // Status-dependent callbacks
+                       statusCode = s.statusCode || {},
+
+                       // Headers (they are sent all at once)
+                       requestHeaders = {},
+                       requestHeadersNames = {},
+
+                       // Default abort message
+                       strAbort = "canceled",
+
+                       // Fake xhr
+                       jqXHR = {
+                               readyState: 0,
+
+                               // Builds headers hashtable if needed
+                               getResponseHeader: function( key ) {
+                                       var match;
+                                       if ( completed ) {
+                                               if ( !responseHeaders ) {
+                                                       responseHeaders = {};
+                                                       while ( ( match = rheaders.exec( 
responseHeadersString ) ) ) {
+                                                               responseHeaders[ match[ 1 ].toLowerCase() ] = 
match[ 2 ];
+                                                       }
+                                               }
+                                               match = responseHeaders[ key.toLowerCase() ];
+                                       }
+                                       return match == null ? null : match;
+                               },
+
+                               // Raw string
+                               getAllResponseHeaders: function() {
+                                       return completed ? responseHeadersString : null;
+                               },
+
+                               // Caches the header
+                               setRequestHeader: function( name, value ) {
+                                       if ( completed == null ) {
+                                               name = requestHeadersNames[ name.toLowerCase() ] =
+                                                       requestHeadersNames[ name.toLowerCase() ] || name;
+                                               requestHeaders[ name ] = value;
+                                       }
+                                       return this;
+                               },
+
+                               // Overrides response content-type header
+                               overrideMimeType: function( type ) {
+                                       if ( completed == null ) {
+                                               s.mimeType = type;
+                                       }
+                                       return this;
+                               },
+
+                               // Status-dependent callbacks
+                               statusCode: function( map ) {
+                                       var code;
+                                       if ( map ) {
+                                               if ( completed ) {
+
+                                                       // Execute the appropriate callbacks
+                                                       jqXHR.always( map[ jqXHR.status ] );
+                                               } else {
+
+                                                       // Lazy-add the new callbacks in a way that preserves 
old ones
+                                                       for ( code in map ) {
+                                                               statusCode[ code ] = [ statusCode[ code ], 
map[ code ] ];
+                                                       }
+                                               }
+                                       }
+                                       return this;
+                               },
+
+                               // Cancel the request
+                               abort: function( statusText ) {
+                                       var finalText = statusText || strAbort;
+                                       if ( transport ) {
+                                               transport.abort( finalText );
+                                       }
+                                       done( 0, finalText );
+                                       return this;
+                               }
+                       };
+
+               // Attach deferreds
+               deferred.promise( jqXHR );
+
+               // Add protocol if not provided (prefilters might expect it)
+               // Handle falsy url in the settings object (#10093: consistency with old signature)
+               // We also use the url parameter if available
+               s.url = ( ( url || s.url || location.href ) + "" )
+                       .replace( rprotocol, location.protocol + "//" );
+
+               // Alias method option to type as per ticket #12004
+               s.type = options.method || options.type || s.method || s.type;
+
+               // Extract dataTypes list
+               s.dataTypes = ( s.dataType || "*" ).toLowerCase().match( rnothtmlwhite ) || [ "" ];
+
+               // A cross-domain request is in order when the origin doesn't match the current origin.
+               if ( s.crossDomain == null ) {
+                       urlAnchor = document.createElement( "a" );
+
+                       // Support: IE <=8 - 11, Edge 12 - 13
+                       // IE throws exception on accessing the href property if url is malformed,
+                       // e.g. http://example.com:80x/
+                       try {
+                               urlAnchor.href = s.url;
+
+                               // Support: IE <=8 - 11 only
+                               // Anchor's host property isn't correctly set when s.url is relative
+                               urlAnchor.href = urlAnchor.href;
+                               s.crossDomain = originAnchor.protocol + "//" + originAnchor.host !==
+                                       urlAnchor.protocol + "//" + urlAnchor.host;
+                       } catch ( e ) {
+
+                               // If there is an error parsing the URL, assume it is crossDomain,
+                               // it can be rejected by the transport if it is invalid
+                               s.crossDomain = true;
+                       }
+               }
+
+               // Convert data if not already a string
+               if ( s.data && s.processData && typeof s.data !== "string" ) {
+                       s.data = jQuery.param( s.data, s.traditional );
+               }
+
+               // Apply prefilters
+               inspectPrefiltersOrTransports( prefilters, s, options, jqXHR );
+
+               // If request was aborted inside a prefilter, stop there
+               if ( completed ) {
+                       return jqXHR;
+               }
+
+               // We can fire global events as of now if asked to
+               // Don't fire events if jQuery.event is undefined in an AMD-usage scenario (#15118)
+               fireGlobals = jQuery.event && s.global;
+
+               // Watch for a new set of requests
+               if ( fireGlobals && jQuery.active++ === 0 ) {
+                       jQuery.event.trigger( "ajaxStart" );
+               }
+
+               // Uppercase the type
+               s.type = s.type.toUpperCase();
+
+               // Determine if request has content
+               s.hasContent = !rnoContent.test( s.type );
+
+               // Save the URL in case we're toying with the If-Modified-Since
+               // and/or If-None-Match header later on
+               // Remove hash to simplify url manipulation
+               cacheURL = s.url.replace( rhash, "" );
+
+               // More options handling for requests with no content
+               if ( !s.hasContent ) {
+
+                       // Remember the hash so we can put it back
+                       uncached = s.url.slice( cacheURL.length );
+
+                       // If data is available, append data to url
+                       if ( s.data ) {
+                               cacheURL += ( rquery.test( cacheURL ) ? "&" : "?" ) + s.data;
+
+                               // #9682: remove data so that it's not used in an eventual retry
+                               delete s.data;
+                       }
+
+                       // Add or update anti-cache param if needed
+                       if ( s.cache === false ) {
+                               cacheURL = cacheURL.replace( rantiCache, "$1" );
+                               uncached = ( rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ( nonce++ ) + 
uncached;
+                       }
+
+                       // Put hash and anti-cache on the URL that will be requested (gh-1732)
+                       s.url = cacheURL + uncached;
+
+               // Change '%20' to '+' if this is encoded form body content (gh-2658)
+               } else if ( s.data && s.processData &&
+                       ( s.contentType || "" ).indexOf( "application/x-www-form-urlencoded" ) === 0 ) {
+                       s.data = s.data.replace( r20, "+" );
+               }
+
+               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+               if ( s.ifModified ) {
+                       if ( jQuery.lastModified[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] 
);
+                       }
+                       if ( jQuery.etag[ cacheURL ] ) {
+                               jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+                       }
+               }
+
+               // Set the correct header, if data is being sent
+               if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) {
+                       jqXHR.setRequestHeader( "Content-Type", s.contentType );
+               }
+
+               // Set the Accepts header for the server, depending on the dataType
+               jqXHR.setRequestHeader(
+                       "Accept",
+                       s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[ 0 ] ] ?
+                               s.accepts[ s.dataTypes[ 0 ] ] +
+                                       ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) :
+                               s.accepts[ "*" ]
+               );
+
+               // Check for headers option
+               for ( i in s.headers ) {
+                       jqXHR.setRequestHeader( i, s.headers[ i ] );
+               }
+
+               // Allow custom headers/mimetypes and early abort
+               if ( s.beforeSend &&
+                       ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || completed ) ) {
+
+                       // Abort if not done already and return
+                       return jqXHR.abort();
+               }
+
+               // Aborting is no longer a cancellation
+               strAbort = "abort";
+
+               // Install callbacks on deferreds
+               completeDeferred.add( s.complete );
+               jqXHR.done( s.success );
+               jqXHR.fail( s.error );
+
+               // Get transport
+               transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR );
+
+               // If no transport, we auto-abort
+               if ( !transport ) {
+                       done( -1, "No Transport" );
+               } else {
+                       jqXHR.readyState = 1;
+
+                       // Send global event
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] );
+                       }
+
+                       // If request was aborted inside ajaxSend, stop there
+                       if ( completed ) {
+                               return jqXHR;
+                       }
+
+                       // Timeout
+                       if ( s.async && s.timeout > 0 ) {
+                               timeoutTimer = window.setTimeout( function() {
+                                       jqXHR.abort( "timeout" );
+                               }, s.timeout );
+                       }
+
+                       try {
+                               completed = false;
+                               transport.send( requestHeaders, done );
+                       } catch ( e ) {
+
+                               // Rethrow post-completion exceptions
+                               if ( completed ) {
+                                       throw e;
+                               }
+
+                               // Propagate others as results
+                               done( -1, e );
+                       }
+               }
+
+               // Callback for when everything is done
+               function done( status, nativeStatusText, responses, headers ) {
+                       var isSuccess, success, error, response, modified,
+                               statusText = nativeStatusText;
+
+                       // Ignore repeat invocations
+                       if ( completed ) {
+                               return;
+                       }
+
+                       completed = true;
+
+                       // Clear timeout if it exists
+                       if ( timeoutTimer ) {
+                               window.clearTimeout( timeoutTimer );
+                       }
+
+                       // Dereference transport for early garbage collection
+                       // (no matter how long the jqXHR object will be used)
+                       transport = undefined;
+
+                       // Cache response headers
+                       responseHeadersString = headers || "";
+
+                       // Set readyState
+                       jqXHR.readyState = status > 0 ? 4 : 0;
+
+                       // Determine if successful
+                       isSuccess = status >= 200 && status < 300 || status === 304;
+
+                       // Get response data
+                       if ( responses ) {
+                               response = ajaxHandleResponses( s, jqXHR, responses );
+                       }
+
+                       // Convert no matter what (that way responseXXX fields are always set)
+                       response = ajaxConvert( s, response, jqXHR, isSuccess );
+
+                       // If successful, handle type chaining
+                       if ( isSuccess ) {
+
+                               // Set the If-Modified-Since and/or If-None-Match header, if in ifModified 
mode.
+                               if ( s.ifModified ) {
+                                       modified = jqXHR.getResponseHeader( "Last-Modified" );
+                                       if ( modified ) {
+                                               jQuery.lastModified[ cacheURL ] = modified;
+                                       }
+                                       modified = jqXHR.getResponseHeader( "etag" );
+                                       if ( modified ) {
+                                               jQuery.etag[ cacheURL ] = modified;
+                                       }
+                               }
+
+                               // if no content
+                               if ( status === 204 || s.type === "HEAD" ) {
+                                       statusText = "nocontent";
+
+                               // if not modified
+                               } else if ( status === 304 ) {
+                                       statusText = "notmodified";
+
+                               // If we have data, let's convert it
+                               } else {
+                                       statusText = response.state;
+                                       success = response.data;
+                                       error = response.error;
+                                       isSuccess = !error;
+                               }
+                       } else {
+
+                               // Extract error from statusText and normalize for non-aborts
+                               error = statusText;
+                               if ( status || !statusText ) {
+                                       statusText = "error";
+                                       if ( status < 0 ) {
+                                               status = 0;
+                                       }
+                               }
+                       }
+
+                       // Set data for the fake xhr object
+                       jqXHR.status = status;
+                       jqXHR.statusText = ( nativeStatusText || statusText ) + "";
+
+                       // Success/Error
+                       if ( isSuccess ) {
+                               deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] );
+                       } else {
+                               deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] );
+                       }
+
+                       // Status-dependent callbacks
+                       jqXHR.statusCode( statusCode );
+                       statusCode = undefined;
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( isSuccess ? "ajaxSuccess" : "ajaxError",
+                                       [ jqXHR, s, isSuccess ? success : error ] );
+                       }
+
+                       // Complete
+                       completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] );
+
+                       if ( fireGlobals ) {
+                               globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] );
+
+                               // Handle the global AJAX counter
+                               if ( !( --jQuery.active ) ) {
+                                       jQuery.event.trigger( "ajaxStop" );
+                               }
+                       }
+               }
+
+               return jqXHR;
+       },
+
+       getJSON: function( url, data, callback ) {
+               return jQuery.get( url, data, callback, "json" );
+       },
+
+       getScript: function( url, callback ) {
+               return jQuery.get( url, undefined, callback, "script" );
+       }
+} );
+
+jQuery.each( [ "get", "post" ], function( i, method ) {
+       jQuery[ method ] = function( url, data, callback, type ) {
+
+               // Shift arguments if data argument was omitted
+               if ( jQuery.isFunction( data ) ) {
+                       type = type || callback;
+                       callback = data;
+                       data = undefined;
+               }
+
+               // The url can be an options object (which then must have .url)
+               return jQuery.ajax( jQuery.extend( {
+                       url: url,
+                       type: method,
+                       dataType: type,
+                       data: data,
+                       success: callback
+               }, jQuery.isPlainObject( url ) && url ) );
+       };
+} );
+
+
+jQuery._evalUrl = function( url ) {
+       return jQuery.ajax( {
+               url: url,
+
+               // Make this explicit, since user can override this through ajaxSetup (#11264)
+               type: "GET",
+               dataType: "script",
+               cache: true,
+               async: false,
+               global: false,
+               "throws": true
+       } );
+};
+
+
+jQuery.fn.extend( {
+       wrapAll: function( html ) {
+               var wrap;
+
+               if ( this[ 0 ] ) {
+                       if ( jQuery.isFunction( html ) ) {
+                               html = html.call( this[ 0 ] );
+                       }
+
+                       // The elements to wrap the target around
+                       wrap = jQuery( html, this[ 0 ].ownerDocument ).eq( 0 ).clone( true );
+
+                       if ( this[ 0 ].parentNode ) {
+                               wrap.insertBefore( this[ 0 ] );
+                       }
+
+                       wrap.map( function() {
+                               var elem = this;
+
+                               while ( elem.firstElementChild ) {
+                                       elem = elem.firstElementChild;
+                               }
+
+                               return elem;
+                       } ).append( this );
+               }
+
+               return this;
+       },
+
+       wrapInner: function( html ) {
+               if ( jQuery.isFunction( html ) ) {
+                       return this.each( function( i ) {
+                               jQuery( this ).wrapInner( html.call( this, i ) );
+                       } );
+               }
+
+               return this.each( function() {
+                       var self = jQuery( this ),
+                               contents = self.contents();
+
+                       if ( contents.length ) {
+                               contents.wrapAll( html );
+
+                       } else {
+                               self.append( html );
+                       }
+               } );
+       },
+
+       wrap: function( html ) {
+               var isFunction = jQuery.isFunction( html );
+
+               return this.each( function( i ) {
+                       jQuery( this ).wrapAll( isFunction ? html.call( this, i ) : html );
+               } );
+       },
+
+       unwrap: function( selector ) {
+               this.parent( selector ).not( "body" ).each( function() {
+                       jQuery( this ).replaceWith( this.childNodes );
+               } );
+               return this;
+       }
+} );
+
+
+jQuery.expr.pseudos.hidden = function( elem ) {
+       return !jQuery.expr.pseudos.visible( elem );
+};
+jQuery.expr.pseudos.visible = function( elem ) {
+       return !!( elem.offsetWidth || elem.offsetHeight || elem.getClientRects().length );
+};
+
+
+
+
+jQuery.ajaxSettings.xhr = function() {
+       try {
+               return new window.XMLHttpRequest();
+       } catch ( e ) {}
+};
+
+var xhrSuccessStatus = {
+
+               // File protocol always yields status code 0, assume 200
+               0: 200,
+
+               // Support: IE <=9 only
+               // #1450: sometimes IE returns 1223 when it should be 204
+               1223: 204
+       },
+       xhrSupported = jQuery.ajaxSettings.xhr();
+
+support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+support.ajax = xhrSupported = !!xhrSupported;
+
+jQuery.ajaxTransport( function( options ) {
+       var callback, errorCallback;
+
+       // Cross domain only allowed if supported through XMLHttpRequest
+       if ( support.cors || xhrSupported && !options.crossDomain ) {
+               return {
+                       send: function( headers, complete ) {
+                               var i,
+                                       xhr = options.xhr();
+
+                               xhr.open(
+                                       options.type,
+                                       options.url,
+                                       options.async,
+                                       options.username,
+                                       options.password
+                               );
+
+                               // Apply custom fields if provided
+                               if ( options.xhrFields ) {
+                                       for ( i in options.xhrFields ) {
+                                               xhr[ i ] = options.xhrFields[ i ];
+                                       }
+                               }
+
+                               // Override mime type if needed
+                               if ( options.mimeType && xhr.overrideMimeType ) {
+                                       xhr.overrideMimeType( options.mimeType );
+                               }
+
+                               // X-Requested-With header
+                               // For cross-domain requests, seeing as conditions for a preflight are
+                               // akin to a jigsaw puzzle, we simply never set it to be sure.
+                               // (it can always be set on a per-request basis or even using ajaxSetup)
+                               // For same-domain requests, won't change header if already provided.
+                               if ( !options.crossDomain && !headers[ "X-Requested-With" ] ) {
+                                       headers[ "X-Requested-With" ] = "XMLHttpRequest";
+                               }
+
+                               // Set headers
+                               for ( i in headers ) {
+                                       xhr.setRequestHeader( i, headers[ i ] );
+                               }
+
+                               // Callback
+                               callback = function( type ) {
+                                       return function() {
+                                               if ( callback ) {
+                                                       callback = errorCallback = xhr.onload =
+                                                               xhr.onerror = xhr.onabort = 
xhr.onreadystatechange = null;
+
+                                                       if ( type === "abort" ) {
+                                                               xhr.abort();
+                                                       } else if ( type === "error" ) {
+
+                                                               // Support: IE <=9 only
+                                                               // On a manual native abort, IE9 throws
+                                                               // errors on any property access that is not 
readyState
+                                                               if ( typeof xhr.status !== "number" ) {
+                                                                       complete( 0, "error" );
+                                                               } else {
+                                                                       complete(
+
+                                                                               // File: protocol always 
yields status 0; see #8605, #14207
+                                                                               xhr.status,
+                                                                               xhr.statusText
+                                                                       );
+                                                               }
+                                                       } else {
+                                                               complete(
+                                                                       xhrSuccessStatus[ xhr.status ] || 
xhr.status,
+                                                                       xhr.statusText,
+
+                                                                       // Support: IE <=9 only
+                                                                       // IE9 has no XHR2 but throws on 
binary (trac-11426)
+                                                                       // For XHR2 non-text, let the caller 
handle it (gh-2498)
+                                                                       ( xhr.responseType || "text" ) !== 
"text"  ||
+                                                                       typeof xhr.responseText !== "string" ?
+                                                                               { binary: xhr.response } :
+                                                                               { text: xhr.responseText },
+                                                                       xhr.getAllResponseHeaders()
+                                                               );
+                                                       }
+                                               }
+                                       };
+                               };
+
+                               // Listen to events
+                               xhr.onload = callback();
+                               errorCallback = xhr.onerror = callback( "error" );
+
+                               // Support: IE 9 only
+                               // Use onreadystatechange to replace onabort
+                               // to handle uncaught aborts
+                               if ( xhr.onabort !== undefined ) {
+                                       xhr.onabort = errorCallback;
+                               } else {
+                                       xhr.onreadystatechange = function() {
+
+                                               // Check readyState before timeout as it changes
+                                               if ( xhr.readyState === 4 ) {
+
+                                                       // Allow onerror to be called first,
+                                                       // but that will not handle a native abort
+                                                       // Also, save errorCallback to a variable
+                                                       // as xhr.onerror cannot be accessed
+                                                       window.setTimeout( function() {
+                                                               if ( callback ) {
+                                                                       errorCallback();
+                                                               }
+                                                       } );
+                                               }
+                                       };
+                               }
+
+                               // Create the abort callback
+                               callback = callback( "abort" );
+
+                               try {
+
+                                       // Do send the request (this may raise an exception)
+                                       xhr.send( options.hasContent && options.data || null );
+                               } catch ( e ) {
+
+                                       // #14683: Only rethrow if this hasn't been notified as an error yet
+                                       if ( callback ) {
+                                               throw e;
+                                       }
+                               }
+                       },
+
+                       abort: function() {
+                               if ( callback ) {
+                                       callback();
+                               }
+                       }
+               };
+       }
+} );
+
+
+
+
+// Prevent auto-execution of scripts when no explicit dataType was provided (See gh-2432)
+jQuery.ajaxPrefilter( function( s ) {
+       if ( s.crossDomain ) {
+               s.contents.script = false;
+       }
+} );
+
+// Install script dataType
+jQuery.ajaxSetup( {
+       accepts: {
+               script: "text/javascript, application/javascript, " +
+                       "application/ecmascript, application/x-ecmascript"
+       },
+       contents: {
+               script: /\b(?:java|ecma)script\b/
+       },
+       converters: {
+               "text script": function( text ) {
+                       jQuery.globalEval( text );
+                       return text;
+               }
+       }
+} );
+
+// Handle cache's special case and crossDomain
+jQuery.ajaxPrefilter( "script", function( s ) {
+       if ( s.cache === undefined ) {
+               s.cache = false;
+       }
+       if ( s.crossDomain ) {
+               s.type = "GET";
+       }
+} );
+
+// Bind script tag hack transport
+jQuery.ajaxTransport( "script", function( s ) {
+
+       // This transport only deals with cross domain requests
+       if ( s.crossDomain ) {
+               var script, callback;
+               return {
+                       send: function( _, complete ) {
+                               script = jQuery( "<script>" ).prop( {
+                                       charset: s.scriptCharset,
+                                       src: s.url
+                               } ).on(
+                                       "load error",
+                                       callback = function( evt ) {
+                                               script.remove();
+                                               callback = null;
+                                               if ( evt ) {
+                                                       complete( evt.type === "error" ? 404 : 200, evt.type 
);
+                                               }
+                                       }
+                               );
+
+                               // Use native DOM manipulation to avoid our domManip AJAX trickery
+                               document.head.appendChild( script[ 0 ] );
+                       },
+                       abort: function() {
+                               if ( callback ) {
+                                       callback();
+                               }
+                       }
+               };
+       }
+} );
+
+
+
+
+var oldCallbacks = [],
+       rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup( {
+       jsonp: "callback",
+       jsonpCallback: function() {
+               var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) );
+               this[ callback ] = true;
+               return callback;
+       }
+} );
+
+// Detect, normalize options and install callbacks for jsonp requests
+jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
+
+       var callbackName, overwritten, responseContainer,
+               jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+                       "url" :
+                       typeof s.data === "string" &&
+                               ( s.contentType || "" )
+                                       .indexOf( "application/x-www-form-urlencoded" ) === 0 &&
+                               rjsonp.test( s.data ) && "data"
+               );
+
+       // Handle iff the expected data type is "jsonp" or we have a parameter to set
+       if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+               // Get callback name, remembering preexisting value associated with it
+               callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+                       s.jsonpCallback() :
+                       s.jsonpCallback;
+
+               // Insert callback into url or form data
+               if ( jsonProp ) {
+                       s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+               } else if ( s.jsonp !== false ) {
+                       s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName;
+               }
+
+               // Use data converter to retrieve json after script execution
+               s.converters[ "script json" ] = function() {
+                       if ( !responseContainer ) {
+                               jQuery.error( callbackName + " was not called" );
+                       }
+                       return responseContainer[ 0 ];
+               };
+
+               // Force json dataType
+               s.dataTypes[ 0 ] = "json";
+
+               // Install callback
+               overwritten = window[ callbackName ];
+               window[ callbackName ] = function() {
+                       responseContainer = arguments;
+               };
+
+               // Clean-up function (fires after converters)
+               jqXHR.always( function() {
+
+                       // If previous value didn't exist - remove it
+                       if ( overwritten === undefined ) {
+                               jQuery( window ).removeProp( callbackName );
+
+                       // Otherwise restore preexisting value
+                       } else {
+                               window[ callbackName ] = overwritten;
+                       }
+
+                       // Save back as free
+                       if ( s[ callbackName ] ) {
+
+                               // Make sure that re-using the options doesn't screw things around
+                               s.jsonpCallback = originalSettings.jsonpCallback;
+
+                               // Save the callback name for future use
+                               oldCallbacks.push( callbackName );
+                       }
+
+                       // Call if it was a function and we have a response
+                       if ( responseContainer && jQuery.isFunction( overwritten ) ) {
+                               overwritten( responseContainer[ 0 ] );
+                       }
+
+                       responseContainer = overwritten = undefined;
+               } );
+
+               // Delegate to script
+               return "script";
+       }
+} );
+
+
+
+
+// Support: Safari 8 only
+// In Safari 8 documents created via document.implementation.createHTMLDocument
+// collapse sibling forms: the second one becomes a child of the first one.
+// Because of that, this security measure has to be disabled in Safari 8.
+// https://bugs.webkit.org/show_bug.cgi?id=137337
+support.createHTMLDocument = ( function() {
+       var body = document.implementation.createHTMLDocument( "" ).body;
+       body.innerHTML = "<form></form><form></form>";
+       return body.childNodes.length === 2;
+} )();
+
+
+// Argument "data" should be string of html
+// context (optional): If specified, the fragment will be created in this context,
+// defaults to document
+// keepScripts (optional): If true, will include scripts passed in the html string
+jQuery.parseHTML = function( data, context, keepScripts ) {
+       if ( typeof data !== "string" ) {
+               return [];
+       }
+       if ( typeof context === "boolean" ) {
+               keepScripts = context;
+               context = false;
+       }
+
+       var base, parsed, scripts;
+
+       if ( !context ) {
+
+               // Stop scripts or inline event handlers from being executed immediately
+               // by using document.implementation
+               if ( support.createHTMLDocument ) {
+                       context = document.implementation.createHTMLDocument( "" );
+
+                       // Set the base href for the created document
+                       // so any parsed elements with URLs
+                       // are based on the document's URL (gh-2965)
+                       base = context.createElement( "base" );
+                       base.href = document.location.href;
+                       context.head.appendChild( base );
+               } else {
+                       context = document;
+               }
+       }
+
+       parsed = rsingleTag.exec( data );
+       scripts = !keepScripts && [];
+
+       // Single tag
+       if ( parsed ) {
+               return [ context.createElement( parsed[ 1 ] ) ];
+       }
+
+       parsed = buildFragment( [ data ], context, scripts );
+
+       if ( scripts && scripts.length ) {
+               jQuery( scripts ).remove();
+       }
+
+       return jQuery.merge( [], parsed.childNodes );
+};
+
+
+/**
+ * Load a url into a page
+ */
+jQuery.fn.load = function( url, params, callback ) {
+       var selector, type, response,
+               self = this,
+               off = url.indexOf( " " );
+
+       if ( off > -1 ) {
+               selector = stripAndCollapse( url.slice( off ) );
+               url = url.slice( 0, off );
+       }
+
+       // If it's a function
+       if ( jQuery.isFunction( params ) ) {
+
+               // We assume that it's the callback
+               callback = params;
+               params = undefined;
+
+       // Otherwise, build a param string
+       } else if ( params && typeof params === "object" ) {
+               type = "POST";
+       }
+
+       // If we have elements to modify, make the request
+       if ( self.length > 0 ) {
+               jQuery.ajax( {
+                       url: url,
+
+                       // If "type" variable is undefined, then "GET" method will be used.
+                       // Make value of this field explicit since
+                       // user can override it through ajaxSetup method
+                       type: type || "GET",
+                       dataType: "html",
+                       data: params
+               } ).done( function( responseText ) {
+
+                       // Save response for use in complete callback
+                       response = arguments;
+
+                       self.html( selector ?
+
+                               // If a selector was specified, locate the right elements in a dummy div
+                               // Exclude scripts to avoid IE 'Permission Denied' errors
+                               jQuery( "<div>" ).append( jQuery.parseHTML( responseText ) ).find( selector ) 
:
+
+                               // Otherwise use the full result
+                               responseText );
+
+               // If the request succeeds, this function gets "data", "status", "jqXHR"
+               // but they are ignored because response was set above.
+               // If it fails, this function gets "jqXHR", "status", "error"
+               } ).always( callback && function( jqXHR, status ) {
+                       self.each( function() {
+                               callback.apply( this, response || [ jqXHR.responseText, status, jqXHR ] );
+                       } );
+               } );
+       }
+
+       return this;
+};
+
+
+
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [
+       "ajaxStart",
+       "ajaxStop",
+       "ajaxComplete",
+       "ajaxError",
+       "ajaxSuccess",
+       "ajaxSend"
+], function( i, type ) {
+       jQuery.fn[ type ] = function( fn ) {
+               return this.on( type, fn );
+       };
+} );
+
+
+
+
+jQuery.expr.pseudos.animated = function( elem ) {
+       return jQuery.grep( jQuery.timers, function( fn ) {
+               return elem === fn.elem;
+       } ).length;
+};
+
+
+
+
+jQuery.offset = {
+       setOffset: function( elem, options, i ) {
+               var curPosition, curLeft, curCSSTop, curTop, curOffset, curCSSLeft, calculatePosition,
+                       position = jQuery.css( elem, "position" ),
+                       curElem = jQuery( elem ),
+                       props = {};
+
+               // Set position first, in-case top/left are set even on static elem
+               if ( position === "static" ) {
+                       elem.style.position = "relative";
+               }
+
+               curOffset = curElem.offset();
+               curCSSTop = jQuery.css( elem, "top" );
+               curCSSLeft = jQuery.css( elem, "left" );
+               calculatePosition = ( position === "absolute" || position === "fixed" ) &&
+                       ( curCSSTop + curCSSLeft ).indexOf( "auto" ) > -1;
+
+               // Need to be able to calculate position if either
+               // top or left is auto and position is either absolute or fixed
+               if ( calculatePosition ) {
+                       curPosition = curElem.position();
+                       curTop = curPosition.top;
+                       curLeft = curPosition.left;
+
+               } else {
+                       curTop = parseFloat( curCSSTop ) || 0;
+                       curLeft = parseFloat( curCSSLeft ) || 0;
+               }
+
+               if ( jQuery.isFunction( options ) ) {
+
+                       // Use jQuery.extend here to allow modification of coordinates argument (gh-1848)
+                       options = options.call( elem, i, jQuery.extend( {}, curOffset ) );
+               }
+
+               if ( options.top != null ) {
+                       props.top = ( options.top - curOffset.top ) + curTop;
+               }
+               if ( options.left != null ) {
+                       props.left = ( options.left - curOffset.left ) + curLeft;
+               }
+
+               if ( "using" in options ) {
+                       options.using.call( elem, props );
+
+               } else {
+                       curElem.css( props );
+               }
+       }
+};
+
+jQuery.fn.extend( {
+       offset: function( options ) {
+
+               // Preserve chaining for setter
+               if ( arguments.length ) {
+                       return options === undefined ?
+                               this :
+                               this.each( function( i ) {
+                                       jQuery.offset.setOffset( this, options, i );
+                               } );
+               }
+
+               var doc, docElem, rect, win,
+                       elem = this[ 0 ];
+
+               if ( !elem ) {
+                       return;
+               }
+
+               // Return zeros for disconnected and hidden (display: none) elements (gh-2310)
+               // Support: IE <=11 only
+               // Running getBoundingClientRect on a
+               // disconnected node in IE throws an error
+               if ( !elem.getClientRects().length ) {
+                       return { top: 0, left: 0 };
+               }
+
+               rect = elem.getBoundingClientRect();
+
+               doc = elem.ownerDocument;
+               docElem = doc.documentElement;
+               win = doc.defaultView;
+
+               return {
+                       top: rect.top + win.pageYOffset - docElem.clientTop,
+                       left: rect.left + win.pageXOffset - docElem.clientLeft
+               };
+       },
+
+       position: function() {
+               if ( !this[ 0 ] ) {
+                       return;
+               }
+
+               var offsetParent, offset,
+                       elem = this[ 0 ],
+                       parentOffset = { top: 0, left: 0 };
+
+               // Fixed elements are offset from window (parentOffset = {top:0, left: 0},
+               // because it is its only offset parent
+               if ( jQuery.css( elem, "position" ) === "fixed" ) {
+
+                       // Assume getBoundingClientRect is there when computed position is fixed
+                       offset = elem.getBoundingClientRect();
+
+               } else {
+
+                       // Get *real* offsetParent
+                       offsetParent = this.offsetParent();
+
+                       // Get correct offsets
+                       offset = this.offset();
+                       if ( !nodeName( offsetParent[ 0 ], "html" ) ) {
+                               parentOffset = offsetParent.offset();
+                       }
+
+                       // Add offsetParent borders
+                       parentOffset = {
+                               top: parentOffset.top + jQuery.css( offsetParent[ 0 ], "borderTopWidth", true 
),
+                               left: parentOffset.left + jQuery.css( offsetParent[ 0 ], "borderLeftWidth", 
true )
+                       };
+               }
+
+               // Subtract parent offsets and element margins
+               return {
+                       top: offset.top - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+                       left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true )
+               };
+       },
+
+       // This method will return documentElement in the following cases:
+       // 1) For the element inside the iframe without offsetParent, this method will return
+       //    documentElement of the parent window
+       // 2) For the hidden or detached element
+       // 3) For body or html element, i.e. in case of the html node - it will return itself
+       //
+       // but those exceptions were never presented as a real life use-cases
+       // and might be considered as more preferable results.
+       //
+       // This logic, however, is not guaranteed and can change at any point in the future
+       offsetParent: function() {
+               return this.map( function() {
+                       var offsetParent = this.offsetParent;
+
+                       while ( offsetParent && jQuery.css( offsetParent, "position" ) === "static" ) {
+                               offsetParent = offsetParent.offsetParent;
+                       }
+
+                       return offsetParent || documentElement;
+               } );
+       }
+} );
+
+// Create scrollLeft and scrollTop methods
+jQuery.each( { scrollLeft: "pageXOffset", scrollTop: "pageYOffset" }, function( method, prop ) {
+       var top = "pageYOffset" === prop;
+
+       jQuery.fn[ method ] = function( val ) {
+               return access( this, function( elem, method, val ) {
+
+                       // Coalesce documents and windows
+                       var win;
+                       if ( jQuery.isWindow( elem ) ) {
+                               win = elem;
+                       } else if ( elem.nodeType === 9 ) {
+                               win = elem.defaultView;
+                       }
+
+                       if ( val === undefined ) {
+                               return win ? win[ prop ] : elem[ method ];
+                       }
+
+                       if ( win ) {
+                               win.scrollTo(
+                                       !top ? val : win.pageXOffset,
+                                       top ? val : win.pageYOffset
+                               );
+
+                       } else {
+                               elem[ method ] = val;
+                       }
+               }, method, val, arguments.length );
+       };
+} );
+
+// Support: Safari <=7 - 9.1, Chrome <=37 - 49
+// Add the top/left cssHooks using jQuery.fn.position
+// Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084
+// Blink bug: https://bugs.chromium.org/p/chromium/issues/detail?id=589347
+// getComputedStyle returns percent when specified for top/left/bottom/right;
+// rather than make the css module depend on the offset module, just check for it here
+jQuery.each( [ "top", "left" ], function( i, prop ) {
+       jQuery.cssHooks[ prop ] = addGetHookIf( support.pixelPosition,
+               function( elem, computed ) {
+                       if ( computed ) {
+                               computed = curCSS( elem, prop );
+
+                               // If curCSS returns percentage, fallback to offset
+                               return rnumnonpx.test( computed ) ?
+                                       jQuery( elem ).position()[ prop ] + "px" :
+                                       computed;
+                       }
+               }
+       );
+} );
+
+
+// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods
+jQuery.each( { Height: "height", Width: "width" }, function( name, type ) {
+       jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name },
+               function( defaultExtra, funcName ) {
+
+               // Margin is only for outerHeight, outerWidth
+               jQuery.fn[ funcName ] = function( margin, value ) {
+                       var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ),
+                               extra = defaultExtra || ( margin === true || value === true ? "margin" : 
"border" );
+
+                       return access( this, function( elem, type, value ) {
+                               var doc;
+
+                               if ( jQuery.isWindow( elem ) ) {
+
+                                       // $( window ).outerWidth/Height return w/h including scrollbars 
(gh-1729)
+                                       return funcName.indexOf( "outer" ) === 0 ?
+                                               elem[ "inner" + name ] :
+                                               elem.document.documentElement[ "client" + name ];
+                               }
+
+                               // Get document width or height
+                               if ( elem.nodeType === 9 ) {
+                                       doc = elem.documentElement;
+
+                                       // Either scroll[Width/Height] or offset[Width/Height] or 
client[Width/Height],
+                                       // whichever is greatest
+                                       return Math.max(
+                                               elem.body[ "scroll" + name ], doc[ "scroll" + name ],
+                                               elem.body[ "offset" + name ], doc[ "offset" + name ],
+                                               doc[ "client" + name ]
+                                       );
+                               }
+
+                               return value === undefined ?
+
+                                       // Get width or height on the element, requesting but not forcing 
parseFloat
+                                       jQuery.css( elem, type, extra ) :
+
+                                       // Set width or height on the element
+                                       jQuery.style( elem, type, value, extra );
+                       }, type, chainable ? margin : undefined, chainable );
+               };
+       } );
+} );
+
+
+jQuery.fn.extend( {
+
+       bind: function( types, data, fn ) {
+               return this.on( types, null, data, fn );
+       },
+       unbind: function( types, fn ) {
+               return this.off( types, null, fn );
+       },
+
+       delegate: function( selector, types, data, fn ) {
+               return this.on( types, selector, data, fn );
+       },
+       undelegate: function( selector, types, fn ) {
+
+               // ( namespace ) or ( selector, types [, fn] )
+               return arguments.length === 1 ?
+                       this.off( selector, "**" ) :
+                       this.off( types, selector || "**", fn );
+       }
+} );
+
+jQuery.holdReady = function( hold ) {
+       if ( hold ) {
+               jQuery.readyWait++;
+       } else {
+               jQuery.ready( true );
+       }
+};
+jQuery.isArray = Array.isArray;
+jQuery.parseJSON = JSON.parse;
+jQuery.nodeName = nodeName;
+
+
+
+
+// Register as a named AMD module, since jQuery can be concatenated with other
+// files that may use define, but not via a proper concatenation script that
+// understands anonymous AMD modules. A named AMD is safest and most robust
+// way to register. Lowercase jquery is used because AMD module names are
+// derived from file names, and jQuery is normally delivered in a lowercase
+// file name. Do this after creating the global so that if an AMD module wants
+// to call noConflict to hide this version of jQuery, it will work.
+
+// Note that for maximum portability, libraries that are not jQuery should
+// declare themselves as anonymous modules, and avoid setting a global if an
+// AMD loader is present. jQuery is a special case. For more information, see
+// https://github.com/jrburke/requirejs/wiki/Updating-existing-libraries#wiki-anon
+
+if ( typeof define === "function" && define.amd ) {
+       define( "jquery", [], function() {
+               return jQuery;
+       } );
+}
+
+
+
+
+var
+
+       // Map over jQuery in case of overwrite
+       _jQuery = window.jQuery,
+
+       // Map over the $ in case of overwrite
+       _$ = window.$;
+
+jQuery.noConflict = function( deep ) {
+       if ( window.$ === jQuery ) {
+               window.$ = _$;
+       }
+
+       if ( deep && window.jQuery === jQuery ) {
+               window.jQuery = _jQuery;
+       }
+
+       return jQuery;
+};
+
+// Expose jQuery and $ identifiers, even in AMD
+// (#7102#comment:10, https://github.com/jquery/jquery/pull/557)
+// and CommonJS for browser emulators (#13566)
+if ( !noGlobal ) {
+       window.jQuery = window.$ = jQuery;
+}
+
+
+
+
+return jQuery;
+} );
diff --git a/src/js/02-popper-1.13.3.js b/src/js/02-popper-1.13.3.js
new file mode 100644
index 0000000..1e79ec9
--- /dev/null
+++ b/src/js/02-popper-1.13.3.js
@@ -0,0 +1,2448 @@
+/**!
+ * @fileOverview Kickass library to create and place poppers near their reference elements.
+ * @version 1.12.3
+ * @license
+ * Copyright (c) 2016 Federico Zivolo and contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in all
+ * copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+(function (global, factory) {
+       typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
+       typeof define === 'function' && define.amd ? define(factory) :
+       (global.Popper = factory());
+}(this, (function () { 'use strict';
+
+var nativeHints = ['native code', '[object MutationObserverConstructor]'];
+
+/**
+ * Determine if a function is implemented natively (as opposed to a polyfill).
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Function | undefined} fn the function to check
+ * @returns {Boolean}
+ */
+var isNative = (function (fn) {
+  return nativeHints.some(function (hint) {
+    return (fn || '').toString().indexOf(hint) > -1;
+  });
+});
+
+var isBrowser = typeof window !== 'undefined';
+var longerTimeoutBrowsers = ['Edge', 'Trident', 'Firefox'];
+var timeoutDuration = 0;
+for (var i = 0; i < longerTimeoutBrowsers.length; i += 1) {
+  if (isBrowser && navigator.userAgent.indexOf(longerTimeoutBrowsers[i]) >= 0) {
+    timeoutDuration = 1;
+    break;
+  }
+}
+
+function microtaskDebounce(fn) {
+  var scheduled = false;
+  var i = 0;
+  var elem = document.createElement('span');
+
+  // MutationObserver provides a mechanism for scheduling microtasks, which
+  // are scheduled *before* the next task. This gives us a way to debounce
+  // a function but ensure it's called *before* the next paint.
+  var observer = new MutationObserver(function () {
+    fn();
+    scheduled = false;
+  });
+
+  observer.observe(elem, { attributes: true });
+
+  return function () {
+    if (!scheduled) {
+      scheduled = true;
+      elem.setAttribute('x-index', i);
+      i = i + 1; // don't use compund (+=) because it doesn't get optimized in V8
+    }
+  };
+}
+
+function taskDebounce(fn) {
+  var scheduled = false;
+  return function () {
+    if (!scheduled) {
+      scheduled = true;
+      setTimeout(function () {
+        scheduled = false;
+        fn();
+      }, timeoutDuration);
+    }
+  };
+}
+
+// It's common for MutationObserver polyfills to be seen in the wild, however
+// these rely on Mutation Events which only occur when an element is connected
+// to the DOM. The algorithm used in this module does not use a connected element,
+// and so we must ensure that a *native* MutationObserver is available.
+var supportsNativeMutationObserver = isBrowser && isNative(window.MutationObserver);
+
+/**
+* Create a debounced version of a method, that's asynchronously deferred
+* but called in the minimum time possible.
+*
+* @method
+* @memberof Popper.Utils
+* @argument {Function} fn
+* @returns {Function}
+*/
+var debounce = supportsNativeMutationObserver ? microtaskDebounce : taskDebounce;
+
+/**
+ * Check if the given variable is a function
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Any} functionToCheck - variable to check
+ * @returns {Boolean} answer to: is a function?
+ */
+function isFunction(functionToCheck) {
+  var getType = {};
+  return functionToCheck && getType.toString.call(functionToCheck) === '[object Function]';
+}
+
+/**
+ * Get CSS computed property of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Eement} element
+ * @argument {String} property
+ */
+function getStyleComputedProperty(element, property) {
+  if (element.nodeType !== 1) {
+    return [];
+  }
+  // NOTE: 1 DOM access here
+  var css = window.getComputedStyle(element, null);
+  return property ? css[property] : css;
+}
+
+/**
+ * Returns the parentNode or the host of the element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} parent
+ */
+function getParentNode(element) {
+  if (element.nodeName === 'HTML') {
+    return element;
+  }
+  return element.parentNode || element.host;
+}
+
+/**
+ * Returns the scrolling parent of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} scroll parent
+ */
+function getScrollParent(element) {
+  // Return body, `getScroll` will take care to get the correct `scrollTop` from it
+  if (!element || ['HTML', 'BODY', '#document'].indexOf(element.nodeName) !== -1) {
+    return window.document.body;
+  }
+
+  // Firefox want us to check `-x` and `-y` variations as well
+
+  var _getStyleComputedProp = getStyleComputedProperty(element),
+      overflow = _getStyleComputedProp.overflow,
+      overflowX = _getStyleComputedProp.overflowX,
+      overflowY = _getStyleComputedProp.overflowY;
+
+  if (/(auto|scroll)/.test(overflow + overflowY + overflowX)) {
+    return element;
+  }
+
+  return getScrollParent(getParentNode(element));
+}
+
+/**
+ * Returns the offset parent of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Element} offset parent
+ */
+function getOffsetParent(element) {
+  // NOTE: 1 DOM access here
+  var offsetParent = element && element.offsetParent;
+  var nodeName = offsetParent && offsetParent.nodeName;
+
+  if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
+    return window.document.documentElement;
+  }
+
+  // .offsetParent will return the closest TD or TABLE in case
+  // no offsetParent is present, I hate this job...
+  if (['TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 && getStyleComputedProperty(offsetParent, 
'position') === 'static') {
+    return getOffsetParent(offsetParent);
+  }
+
+  return offsetParent;
+}
+
+function isOffsetContainer(element) {
+  var nodeName = element.nodeName;
+
+  if (nodeName === 'BODY') {
+    return false;
+  }
+  return nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element;
+}
+
+/**
+ * Finds the root node (document, shadowDOM root) of the given element
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} node
+ * @returns {Element} root node
+ */
+function getRoot(node) {
+  if (node.parentNode !== null) {
+    return getRoot(node.parentNode);
+  }
+
+  return node;
+}
+
+/**
+ * Finds the offset parent common to the two provided nodes
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element1
+ * @argument {Element} element2
+ * @returns {Element} common offset parent
+ */
+function findCommonOffsetParent(element1, element2) {
+  // This check is needed to avoid errors in case one of the elements isn't defined for any reason
+  if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
+    return window.document.documentElement;
+  }
+
+  // Here we make sure to give as "start" the element that comes first in the DOM
+  var order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
+  var start = order ? element1 : element2;
+  var end = order ? element2 : element1;
+
+  // Get common ancestor container
+  var range = document.createRange();
+  range.setStart(start, 0);
+  range.setEnd(end, 0);
+  var commonAncestorContainer = range.commonAncestorContainer;
+
+  // Both nodes are inside #document
+
+  if (element1 !== commonAncestorContainer && element2 !== commonAncestorContainer || start.contains(end)) {
+    if (isOffsetContainer(commonAncestorContainer)) {
+      return commonAncestorContainer;
+    }
+
+    return getOffsetParent(commonAncestorContainer);
+  }
+
+  // one of the nodes is inside shadowDOM, find which one
+  var element1root = getRoot(element1);
+  if (element1root.host) {
+    return findCommonOffsetParent(element1root.host, element2);
+  } else {
+    return findCommonOffsetParent(element1, getRoot(element2).host);
+  }
+}
+
+/**
+ * Gets the scroll value of the given element in the given side (top and left)
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @argument {String} side `top` or `left`
+ * @returns {number} amount of scrolled pixels
+ */
+function getScroll(element) {
+  var side = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'top';
+
+  var upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
+  var nodeName = element.nodeName;
+
+  if (nodeName === 'BODY' || nodeName === 'HTML') {
+    var html = window.document.documentElement;
+    var scrollingElement = window.document.scrollingElement || html;
+    return scrollingElement[upperSide];
+  }
+
+  return element[upperSide];
+}
+
+/*
+ * Sum or subtract the element scroll values (left and top) from a given rect object
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} rect - Rect object you want to change
+ * @param {HTMLElement} element - The element from the function reads the scroll values
+ * @param {Boolean} subtract - set to true if you want to subtract the scroll values
+ * @return {Object} rect - The modifier rect object
+ */
+function includeScroll(rect, element) {
+  var subtract = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : false;
+
+  var scrollTop = getScroll(element, 'top');
+  var scrollLeft = getScroll(element, 'left');
+  var modifier = subtract ? -1 : 1;
+  rect.top += scrollTop * modifier;
+  rect.bottom += scrollTop * modifier;
+  rect.left += scrollLeft * modifier;
+  rect.right += scrollLeft * modifier;
+  return rect;
+}
+
+/*
+ * Helper to detect borders of a given element
+ * @method
+ * @memberof Popper.Utils
+ * @param {CSSStyleDeclaration} styles
+ * Result of `getStyleComputedProperty` on the given element
+ * @param {String} axis - `x` or `y`
+ * @return {number} borders - The borders size of the given axis
+ */
+
+function getBordersSize(styles, axis) {
+  var sideA = axis === 'x' ? 'Left' : 'Top';
+  var sideB = sideA === 'Left' ? 'Right' : 'Bottom';
+
+  return +styles['border' + sideA + 'Width'].split('px')[0] + +styles['border' + sideB + 
'Width'].split('px')[0];
+}
+
+/**
+ * Tells if you are running Internet Explorer 10
+ * @method
+ * @memberof Popper.Utils
+ * @returns {Boolean} isIE10
+ */
+var isIE10 = undefined;
+
+var isIE10$1 = function () {
+  if (isIE10 === undefined) {
+    isIE10 = navigator.appVersion.indexOf('MSIE 10') !== -1;
+  }
+  return isIE10;
+};
+
+function getSize(axis, body, html, computedStyle) {
+  return Math.max(body['offset' + axis], body['scroll' + axis], html['client' + axis], html['offset' + 
axis], html['scroll' + axis], isIE10$1() ? html['offset' + axis] + computedStyle['margin' + (axis === 
'Height' ? 'Top' : 'Left')] + computedStyle['margin' + (axis === 'Height' ? 'Bottom' : 'Right')] : 0);
+}
+
+function getWindowSizes() {
+  var body = window.document.body;
+  var html = window.document.documentElement;
+  var computedStyle = isIE10$1() && window.getComputedStyle(html);
+
+  return {
+    height: getSize('Height', body, html, computedStyle),
+    width: getSize('Width', body, html, computedStyle)
+  };
+}
+
+var classCallCheck = function (instance, Constructor) {
+  if (!(instance instanceof Constructor)) {
+    throw new TypeError("Cannot call a class as a function");
+  }
+};
+
+var createClass = function () {
+  function defineProperties(target, props) {
+    for (var i = 0; i < props.length; i++) {
+      var descriptor = props[i];
+      descriptor.enumerable = descriptor.enumerable || false;
+      descriptor.configurable = true;
+      if ("value" in descriptor) descriptor.writable = true;
+      Object.defineProperty(target, descriptor.key, descriptor);
+    }
+  }
+
+  return function (Constructor, protoProps, staticProps) {
+    if (protoProps) defineProperties(Constructor.prototype, protoProps);
+    if (staticProps) defineProperties(Constructor, staticProps);
+    return Constructor;
+  };
+}();
+
+
+
+
+
+var defineProperty = function (obj, key, value) {
+  if (key in obj) {
+    Object.defineProperty(obj, key, {
+      value: value,
+      enumerable: true,
+      configurable: true,
+      writable: true
+    });
+  } else {
+    obj[key] = value;
+  }
+
+  return obj;
+};
+
+var _extends = Object.assign || function (target) {
+  for (var i = 1; i < arguments.length; i++) {
+    var source = arguments[i];
+
+    for (var key in source) {
+      if (Object.prototype.hasOwnProperty.call(source, key)) {
+        target[key] = source[key];
+      }
+    }
+  }
+
+  return target;
+};
+
+/**
+ * Given element offsets, generate an output similar to getBoundingClientRect
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Object} offsets
+ * @returns {Object} ClientRect like output
+ */
+function getClientRect(offsets) {
+  return _extends({}, offsets, {
+    right: offsets.left + offsets.width,
+    bottom: offsets.top + offsets.height
+  });
+}
+
+/**
+ * Get bounding client rect of given element
+ * @method
+ * @memberof Popper.Utils
+ * @param {HTMLElement} element
+ * @return {Object} client rect
+ */
+function getBoundingClientRect(element) {
+  var rect = {};
+
+  // IE10 10 FIX: Please, don't ask, the element isn't
+  // considered in DOM in some circumstances...
+  // This isn't reproducible in IE10 compatibility mode of IE11
+  if (isIE10$1()) {
+    try {
+      rect = element.getBoundingClientRect();
+      var scrollTop = getScroll(element, 'top');
+      var scrollLeft = getScroll(element, 'left');
+      rect.top += scrollTop;
+      rect.left += scrollLeft;
+      rect.bottom += scrollTop;
+      rect.right += scrollLeft;
+    } catch (err) {}
+  } else {
+    rect = element.getBoundingClientRect();
+  }
+
+  var result = {
+    left: rect.left,
+    top: rect.top,
+    width: rect.right - rect.left,
+    height: rect.bottom - rect.top
+  };
+
+  // subtract scrollbar size from sizes
+  var sizes = element.nodeName === 'HTML' ? getWindowSizes() : {};
+  var width = sizes.width || element.clientWidth || result.right - result.left;
+  var height = sizes.height || element.clientHeight || result.bottom - result.top;
+
+  var horizScrollbar = element.offsetWidth - width;
+  var vertScrollbar = element.offsetHeight - height;
+
+  // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
+  // we make this check conditional for performance reasons
+  if (horizScrollbar || vertScrollbar) {
+    var styles = getStyleComputedProperty(element);
+    horizScrollbar -= getBordersSize(styles, 'x');
+    vertScrollbar -= getBordersSize(styles, 'y');
+
+    result.width -= horizScrollbar;
+    result.height -= vertScrollbar;
+  }
+
+  return getClientRect(result);
+}
+
+function getOffsetRectRelativeToArbitraryNode(children, parent) {
+  var isIE10 = isIE10$1();
+  var isHTML = parent.nodeName === 'HTML';
+  var childrenRect = getBoundingClientRect(children);
+  var parentRect = getBoundingClientRect(parent);
+  var scrollParent = getScrollParent(children);
+
+  var styles = getStyleComputedProperty(parent);
+  var borderTopWidth = +styles.borderTopWidth.split('px')[0];
+  var borderLeftWidth = +styles.borderLeftWidth.split('px')[0];
+
+  var offsets = getClientRect({
+    top: childrenRect.top - parentRect.top - borderTopWidth,
+    left: childrenRect.left - parentRect.left - borderLeftWidth,
+    width: childrenRect.width,
+    height: childrenRect.height
+  });
+  offsets.marginTop = 0;
+  offsets.marginLeft = 0;
+
+  // Subtract margins of documentElement in case it's being used as parent
+  // we do this only on HTML because it's the only element that behaves
+  // differently when margins are applied to it. The margins are included in
+  // the box of the documentElement, in the other cases not.
+  if (!isIE10 && isHTML) {
+    var marginTop = +styles.marginTop.split('px')[0];
+    var marginLeft = +styles.marginLeft.split('px')[0];
+
+    offsets.top -= borderTopWidth - marginTop;
+    offsets.bottom -= borderTopWidth - marginTop;
+    offsets.left -= borderLeftWidth - marginLeft;
+    offsets.right -= borderLeftWidth - marginLeft;
+
+    // Attach marginTop and marginLeft because in some circumstances we may need them
+    offsets.marginTop = marginTop;
+    offsets.marginLeft = marginLeft;
+  }
+
+  if (isIE10 ? parent.contains(scrollParent) : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
+    offsets = includeScroll(offsets, parent);
+  }
+
+  return offsets;
+}
+
+function getViewportOffsetRectRelativeToArtbitraryNode(element) {
+  var html = window.document.documentElement;
+  var relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
+  var width = Math.max(html.clientWidth, window.innerWidth || 0);
+  var height = Math.max(html.clientHeight, window.innerHeight || 0);
+
+  var scrollTop = getScroll(html);
+  var scrollLeft = getScroll(html, 'left');
+
+  var offset = {
+    top: scrollTop - relativeOffset.top + relativeOffset.marginTop,
+    left: scrollLeft - relativeOffset.left + relativeOffset.marginLeft,
+    width: width,
+    height: height
+  };
+
+  return getClientRect(offset);
+}
+
+/**
+ * Check if the given element is fixed or is inside a fixed parent
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @argument {Element} customContainer
+ * @returns {Boolean} answer to "isFixed?"
+ */
+function isFixed(element) {
+  var nodeName = element.nodeName;
+  if (nodeName === 'BODY' || nodeName === 'HTML') {
+    return false;
+  }
+  if (getStyleComputedProperty(element, 'position') === 'fixed') {
+    return true;
+  }
+  return isFixed(getParentNode(element));
+}
+
+/**
+ * Computed the boundaries limits and return them
+ * @method
+ * @memberof Popper.Utils
+ * @param {HTMLElement} popper
+ * @param {HTMLElement} reference
+ * @param {number} padding
+ * @param {HTMLElement} boundariesElement - Element used to define the boundaries
+ * @returns {Object} Coordinates of the boundaries
+ */
+function getBoundaries(popper, reference, padding, boundariesElement) {
+  // NOTE: 1 DOM access here
+  var boundaries = { top: 0, left: 0 };
+  var offsetParent = findCommonOffsetParent(popper, reference);
+
+  // Handle viewport case
+  if (boundariesElement === 'viewport') {
+    boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent);
+  } else {
+    // Handle other cases based on DOM element used as boundaries
+    var boundariesNode = void 0;
+    if (boundariesElement === 'scrollParent') {
+      boundariesNode = getScrollParent(getParentNode(popper));
+      if (boundariesNode.nodeName === 'BODY') {
+        boundariesNode = window.document.documentElement;
+      }
+    } else if (boundariesElement === 'window') {
+      boundariesNode = window.document.documentElement;
+    } else {
+      boundariesNode = boundariesElement;
+    }
+
+    var offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent);
+
+    // In case of HTML, we need a different computation
+    if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
+      var _getWindowSizes = getWindowSizes(),
+          height = _getWindowSizes.height,
+          width = _getWindowSizes.width;
+
+      boundaries.top += offsets.top - offsets.marginTop;
+      boundaries.bottom = height + offsets.top;
+      boundaries.left += offsets.left - offsets.marginLeft;
+      boundaries.right = width + offsets.left;
+    } else {
+      // for all the other DOM elements, this one is good
+      boundaries = offsets;
+    }
+  }
+
+  // Add paddings
+  boundaries.left += padding;
+  boundaries.top += padding;
+  boundaries.right -= padding;
+  boundaries.bottom -= padding;
+
+  return boundaries;
+}
+
+function getArea(_ref) {
+  var width = _ref.width,
+      height = _ref.height;
+
+  return width * height;
+}
+
+/**
+ * Utility used to transform the `auto` placement to the placement with more
+ * available space.
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function computeAutoPlacement(placement, refRect, popper, reference, boundariesElement) {
+  var padding = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
+
+  if (placement.indexOf('auto') === -1) {
+    return placement;
+  }
+
+  var boundaries = getBoundaries(popper, reference, padding, boundariesElement);
+
+  var rects = {
+    top: {
+      width: boundaries.width,
+      height: refRect.top - boundaries.top
+    },
+    right: {
+      width: boundaries.right - refRect.right,
+      height: boundaries.height
+    },
+    bottom: {
+      width: boundaries.width,
+      height: boundaries.bottom - refRect.bottom
+    },
+    left: {
+      width: refRect.left - boundaries.left,
+      height: boundaries.height
+    }
+  };
+
+  var sortedAreas = Object.keys(rects).map(function (key) {
+    return _extends({
+      key: key
+    }, rects[key], {
+      area: getArea(rects[key])
+    });
+  }).sort(function (a, b) {
+    return b.area - a.area;
+  });
+
+  var filteredAreas = sortedAreas.filter(function (_ref2) {
+    var width = _ref2.width,
+        height = _ref2.height;
+    return width >= popper.clientWidth && height >= popper.clientHeight;
+  });
+
+  var computedPlacement = filteredAreas.length > 0 ? filteredAreas[0].key : sortedAreas[0].key;
+
+  var variation = placement.split('-')[1];
+
+  return computedPlacement + (variation ? '-' + variation : '');
+}
+
+/**
+ * Get offsets to the reference element
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} state
+ * @param {Element} popper - the popper element
+ * @param {Element} reference - the reference element (the popper will be relative to this)
+ * @returns {Object} An object containing the offsets which will be applied to the popper
+ */
+function getReferenceOffsets(state, popper, reference) {
+  var commonOffsetParent = findCommonOffsetParent(popper, reference);
+  return getOffsetRectRelativeToArbitraryNode(reference, commonOffsetParent);
+}
+
+/**
+ * Get the outer sizes of the given element (offset size + margins)
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element
+ * @returns {Object} object containing width and height properties
+ */
+function getOuterSizes(element) {
+  var styles = window.getComputedStyle(element);
+  var x = parseFloat(styles.marginTop) + parseFloat(styles.marginBottom);
+  var y = parseFloat(styles.marginLeft) + parseFloat(styles.marginRight);
+  var result = {
+    width: element.offsetWidth + y,
+    height: element.offsetHeight + x
+  };
+  return result;
+}
+
+/**
+ * Get the opposite placement of the given one
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} placement
+ * @returns {String} flipped placement
+ */
+function getOppositePlacement(placement) {
+  var hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
+  return placement.replace(/left|right|bottom|top/g, function (matched) {
+    return hash[matched];
+  });
+}
+
+/**
+ * Get offsets to the popper
+ * @method
+ * @memberof Popper.Utils
+ * @param {Object} position - CSS position the Popper will get applied
+ * @param {HTMLElement} popper - the popper element
+ * @param {Object} referenceOffsets - the reference offsets (the popper will be relative to this)
+ * @param {String} placement - one of the valid placement options
+ * @returns {Object} popperOffsets - An object containing the offsets which will be applied to the popper
+ */
+function getPopperOffsets(popper, referenceOffsets, placement) {
+  placement = placement.split('-')[0];
+
+  // Get popper node sizes
+  var popperRect = getOuterSizes(popper);
+
+  // Add position, width and height to our offsets object
+  var popperOffsets = {
+    width: popperRect.width,
+    height: popperRect.height
+  };
+
+  // depending by the popper placement we have to compute its offsets slightly differently
+  var isHoriz = ['right', 'left'].indexOf(placement) !== -1;
+  var mainSide = isHoriz ? 'top' : 'left';
+  var secondarySide = isHoriz ? 'left' : 'top';
+  var measurement = isHoriz ? 'height' : 'width';
+  var secondaryMeasurement = !isHoriz ? 'height' : 'width';
+
+  popperOffsets[mainSide] = referenceOffsets[mainSide] + referenceOffsets[measurement] / 2 - 
popperRect[measurement] / 2;
+  if (placement === secondarySide) {
+    popperOffsets[secondarySide] = referenceOffsets[secondarySide] - popperRect[secondaryMeasurement];
+  } else {
+    popperOffsets[secondarySide] = referenceOffsets[getOppositePlacement(secondarySide)];
+  }
+
+  return popperOffsets;
+}
+
+/**
+ * Mimics the `find` method of Array
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Array} arr
+ * @argument prop
+ * @argument value
+ * @returns index or -1
+ */
+function find(arr, check) {
+  // use native find if supported
+  if (Array.prototype.find) {
+    return arr.find(check);
+  }
+
+  // use `filter` to obtain the same behavior of `find`
+  return arr.filter(check)[0];
+}
+
+/**
+ * Return the index of the matching object
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Array} arr
+ * @argument prop
+ * @argument value
+ * @returns index or -1
+ */
+function findIndex(arr, prop, value) {
+  // use native findIndex if supported
+  if (Array.prototype.findIndex) {
+    return arr.findIndex(function (cur) {
+      return cur[prop] === value;
+    });
+  }
+
+  // use `find` + `indexOf` if `findIndex` isn't supported
+  var match = find(arr, function (obj) {
+    return obj[prop] === value;
+  });
+  return arr.indexOf(match);
+}
+
+/**
+ * Loop trough the list of modifiers and run them in order,
+ * each of them will then edit the data object.
+ * @method
+ * @memberof Popper.Utils
+ * @param {dataObject} data
+ * @param {Array} modifiers
+ * @param {String} ends - Optional modifier name used as stopper
+ * @returns {dataObject}
+ */
+function runModifiers(modifiers, data, ends) {
+  var modifiersToRun = ends === undefined ? modifiers : modifiers.slice(0, findIndex(modifiers, 'name', 
ends));
+
+  modifiersToRun.forEach(function (modifier) {
+    if (modifier.function) {
+      console.warn('`modifier.function` is deprecated, use `modifier.fn`!');
+    }
+    var fn = modifier.function || modifier.fn;
+    if (modifier.enabled && isFunction(fn)) {
+      // Add properties to offsets to make them a complete clientRect object
+      // we do this before each modifier to make sure the previous one doesn't
+      // mess with these values
+      data.offsets.popper = getClientRect(data.offsets.popper);
+      data.offsets.reference = getClientRect(data.offsets.reference);
+
+      data = fn(data, modifier);
+    }
+  });
+
+  return data;
+}
+
+/**
+ * Updates the position of the popper, computing the new offsets and applying
+ * the new style.<br />
+ * Prefer `scheduleUpdate` over `update` because of performance reasons.
+ * @method
+ * @memberof Popper
+ */
+function update() {
+  // if popper is destroyed, don't perform any further update
+  if (this.state.isDestroyed) {
+    return;
+  }
+
+  var data = {
+    instance: this,
+    styles: {},
+    arrowStyles: {},
+    attributes: {},
+    flipped: false,
+    offsets: {}
+  };
+
+  // compute reference element offsets
+  data.offsets.reference = getReferenceOffsets(this.state, this.popper, this.reference);
+
+  // compute auto placement, store placement inside the data object,
+  // modifiers will be able to edit `placement` if needed
+  // and refer to originalPlacement to know the original value
+  data.placement = computeAutoPlacement(this.options.placement, data.offsets.reference, this.popper, 
this.reference, this.options.modifiers.flip.boundariesElement, this.options.modifiers.flip.padding);
+
+  // store the computed placement inside `originalPlacement`
+  data.originalPlacement = data.placement;
+
+  // compute the popper offsets
+  data.offsets.popper = getPopperOffsets(this.popper, data.offsets.reference, data.placement);
+  data.offsets.popper.position = 'absolute';
+
+  // run the modifiers
+  data = runModifiers(this.modifiers, data);
+
+  // the first `update` will call `onCreate` callback
+  // the other ones will call `onUpdate` callback
+  if (!this.state.isCreated) {
+    this.state.isCreated = true;
+    this.options.onCreate(data);
+  } else {
+    this.options.onUpdate(data);
+  }
+}
+
+/**
+ * Helper used to know if the given modifier is enabled.
+ * @method
+ * @memberof Popper.Utils
+ * @returns {Boolean}
+ */
+function isModifierEnabled(modifiers, modifierName) {
+  return modifiers.some(function (_ref) {
+    var name = _ref.name,
+        enabled = _ref.enabled;
+    return enabled && name === modifierName;
+  });
+}
+
+/**
+ * Get the prefixed supported property name
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} property (camelCase)
+ * @returns {String} prefixed property (camelCase or PascalCase, depending on the vendor prefix)
+ */
+function getSupportedPropertyName(property) {
+  var prefixes = [false, 'ms', 'Webkit', 'Moz', 'O'];
+  var upperProp = property.charAt(0).toUpperCase() + property.slice(1);
+
+  for (var i = 0; i < prefixes.length - 1; i++) {
+    var prefix = prefixes[i];
+    var toCheck = prefix ? '' + prefix + upperProp : property;
+    if (typeof window.document.body.style[toCheck] !== 'undefined') {
+      return toCheck;
+    }
+  }
+  return null;
+}
+
+/**
+ * Destroy the popper
+ * @method
+ * @memberof Popper
+ */
+function destroy() {
+  this.state.isDestroyed = true;
+
+  // touch DOM only if `applyStyle` modifier is enabled
+  if (isModifierEnabled(this.modifiers, 'applyStyle')) {
+    this.popper.removeAttribute('x-placement');
+    this.popper.style.left = '';
+    this.popper.style.position = '';
+    this.popper.style.top = '';
+    this.popper.style[getSupportedPropertyName('transform')] = '';
+  }
+
+  this.disableEventListeners();
+
+  // remove the popper if user explicity asked for the deletion on destroy
+  // do not use `remove` because IE11 doesn't support it
+  if (this.options.removeOnDestroy) {
+    this.popper.parentNode.removeChild(this.popper);
+  }
+  return this;
+}
+
+function attachToScrollParents(scrollParent, event, callback, scrollParents) {
+  var isBody = scrollParent.nodeName === 'BODY';
+  var target = isBody ? window : scrollParent;
+  target.addEventListener(event, callback, { passive: true });
+
+  if (!isBody) {
+    attachToScrollParents(getScrollParent(target.parentNode), event, callback, scrollParents);
+  }
+  scrollParents.push(target);
+}
+
+/**
+ * Setup needed event listeners used to update the popper position
+ * @method
+ * @memberof Popper.Utils
+ * @private
+ */
+function setupEventListeners(reference, options, state, updateBound) {
+  // Resize event listener on window
+  state.updateBound = updateBound;
+  window.addEventListener('resize', state.updateBound, { passive: true });
+
+  // Scroll event listener on scroll parents
+  var scrollElement = getScrollParent(reference);
+  attachToScrollParents(scrollElement, 'scroll', state.updateBound, state.scrollParents);
+  state.scrollElement = scrollElement;
+  state.eventsEnabled = true;
+
+  return state;
+}
+
+/**
+ * It will add resize/scroll events and start recalculating
+ * position of the popper element when they are triggered.
+ * @method
+ * @memberof Popper
+ */
+function enableEventListeners() {
+  if (!this.state.eventsEnabled) {
+    this.state = setupEventListeners(this.reference, this.options, this.state, this.scheduleUpdate);
+  }
+}
+
+/**
+ * Remove event listeners used to update the popper position
+ * @method
+ * @memberof Popper.Utils
+ * @private
+ */
+function removeEventListeners(reference, state) {
+  // Remove resize event listener on window
+  window.removeEventListener('resize', state.updateBound);
+
+  // Remove scroll event listener on scroll parents
+  state.scrollParents.forEach(function (target) {
+    target.removeEventListener('scroll', state.updateBound);
+  });
+
+  // Reset state
+  state.updateBound = null;
+  state.scrollParents = [];
+  state.scrollElement = null;
+  state.eventsEnabled = false;
+  return state;
+}
+
+/**
+ * It will remove resize/scroll events and won't recalculate popper position
+ * when they are triggered. It also won't trigger onUpdate callback anymore,
+ * unless you call `update` method manually.
+ * @method
+ * @memberof Popper
+ */
+function disableEventListeners() {
+  if (this.state.eventsEnabled) {
+    window.cancelAnimationFrame(this.scheduleUpdate);
+    this.state = removeEventListeners(this.reference, this.state);
+  }
+}
+
+/**
+ * Tells if a given input is a number
+ * @method
+ * @memberof Popper.Utils
+ * @param {*} input to check
+ * @return {Boolean}
+ */
+function isNumeric(n) {
+  return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
+}
+
+/**
+ * Set the style to the given popper
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element - Element to apply the style to
+ * @argument {Object} styles
+ * Object with a list of properties and values which will be applied to the element
+ */
+function setStyles(element, styles) {
+  Object.keys(styles).forEach(function (prop) {
+    var unit = '';
+    // add unit if the value is numeric and is one of the following
+    if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 && 
isNumeric(styles[prop])) {
+      unit = 'px';
+    }
+    element.style[prop] = styles[prop] + unit;
+  });
+}
+
+/**
+ * Set the attributes to the given popper
+ * @method
+ * @memberof Popper.Utils
+ * @argument {Element} element - Element to apply the attributes to
+ * @argument {Object} styles
+ * Object with a list of properties and values which will be applied to the element
+ */
+function setAttributes(element, attributes) {
+  Object.keys(attributes).forEach(function (prop) {
+    var value = attributes[prop];
+    if (value !== false) {
+      element.setAttribute(prop, attributes[prop]);
+    } else {
+      element.removeAttribute(prop);
+    }
+  });
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} data.styles - List of style properties - values to apply to popper element
+ * @argument {Object} data.attributes - List of attribute properties - values to apply to popper element
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The same data object
+ */
+function applyStyle(data) {
+  // any property present in `data.styles` will be applied to the popper,
+  // in this way we can make the 3rd party modifiers add custom styles to it
+  // Be aware, modifiers could override the properties defined in the previous
+  // lines of this modifier!
+  setStyles(data.instance.popper, data.styles);
+
+  // any property present in `data.attributes` will be applied to the popper,
+  // they will be set as HTML attributes of the element
+  setAttributes(data.instance.popper, data.attributes);
+
+  // if arrowElement is defined and arrowStyles has some properties
+  if (data.arrowElement && Object.keys(data.arrowStyles).length) {
+    setStyles(data.arrowElement, data.arrowStyles);
+  }
+
+  return data;
+}
+
+/**
+ * Set the x-placement attribute before everything else because it could be used
+ * to add margins to the popper margins needs to be calculated to get the
+ * correct popper offsets.
+ * @method
+ * @memberof Popper.modifiers
+ * @param {HTMLElement} reference - The reference element used to position the popper
+ * @param {HTMLElement} popper - The HTML element used as popper.
+ * @param {Object} options - Popper.js options
+ */
+function applyStyleOnLoad(reference, popper, options, modifierOptions, state) {
+  // compute reference element offsets
+  var referenceOffsets = getReferenceOffsets(state, popper, reference);
+
+  // compute auto placement, store placement inside the data object,
+  // modifiers will be able to edit `placement` if needed
+  // and refer to originalPlacement to know the original value
+  var placement = computeAutoPlacement(options.placement, referenceOffsets, popper, reference, 
options.modifiers.flip.boundariesElement, options.modifiers.flip.padding);
+
+  popper.setAttribute('x-placement', placement);
+
+  // Apply `position` to popper before anything else because
+  // without the position applied we can't guarantee correct computations
+  setStyles(popper, { position: 'absolute' });
+
+  return options;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function computeStyle(data, options) {
+  var x = options.x,
+      y = options.y;
+  var popper = data.offsets.popper;
+
+  // Remove this legacy support in Popper.js v2
+
+  var legacyGpuAccelerationOption = find(data.instance.modifiers, function (modifier) {
+    return modifier.name === 'applyStyle';
+  }).gpuAcceleration;
+  if (legacyGpuAccelerationOption !== undefined) {
+    console.warn('WARNING: `gpuAcceleration` option moved to `computeStyle` modifier and will not be 
supported in future versions of Popper.js!');
+  }
+  var gpuAcceleration = legacyGpuAccelerationOption !== undefined ? legacyGpuAccelerationOption : 
options.gpuAcceleration;
+
+  var offsetParent = getOffsetParent(data.instance.popper);
+  var offsetParentRect = getBoundingClientRect(offsetParent);
+
+  // Styles
+  var styles = {
+    position: popper.position
+  };
+
+  // floor sides to avoid blurry text
+  var offsets = {
+    left: Math.floor(popper.left),
+    top: Math.floor(popper.top),
+    bottom: Math.floor(popper.bottom),
+    right: Math.floor(popper.right)
+  };
+
+  var sideA = x === 'bottom' ? 'top' : 'bottom';
+  var sideB = y === 'right' ? 'left' : 'right';
+
+  // if gpuAcceleration is set to `true` and transform is supported,
+  //  we use `translate3d` to apply the position to the popper we
+  // automatically use the supported prefixed version if needed
+  var prefixedProperty = getSupportedPropertyName('transform');
+
+  // now, let's make a step back and look at this code closely (wtf?)
+  // If the content of the popper grows once it's been positioned, it
+  // may happen that the popper gets misplaced because of the new content
+  // overflowing its reference element
+  // To avoid this problem, we provide two options (x and y), which allow
+  // the consumer to define the offset origin.
+  // If we position a popper on top of a reference element, we can set
+  // `x` to `top` to make the popper grow towards its top instead of
+  // its bottom.
+  var left = void 0,
+      top = void 0;
+  if (sideA === 'bottom') {
+    top = -offsetParentRect.height + offsets.bottom;
+  } else {
+    top = offsets.top;
+  }
+  if (sideB === 'right') {
+    left = -offsetParentRect.width + offsets.right;
+  } else {
+    left = offsets.left;
+  }
+  if (gpuAcceleration && prefixedProperty) {
+    styles[prefixedProperty] = 'translate3d(' + left + 'px, ' + top + 'px, 0)';
+    styles[sideA] = 0;
+    styles[sideB] = 0;
+    styles.willChange = 'transform';
+  } else {
+    // othwerise, we use the standard `top`, `left`, `bottom` and `right` properties
+    var invertTop = sideA === 'bottom' ? -1 : 1;
+    var invertLeft = sideB === 'right' ? -1 : 1;
+    styles[sideA] = top * invertTop;
+    styles[sideB] = left * invertLeft;
+    styles.willChange = sideA + ', ' + sideB;
+  }
+
+  // Attributes
+  var attributes = {
+    'x-placement': data.placement
+  };
+
+  // Update `data` attributes, styles and arrowStyles
+  data.attributes = _extends({}, attributes, data.attributes);
+  data.styles = _extends({}, styles, data.styles);
+  data.arrowStyles = _extends({}, data.offsets.arrow, data.arrowStyles);
+
+  return data;
+}
+
+/**
+ * Helper used to know if the given modifier depends from another one.<br />
+ * It checks if the needed modifier is listed and enabled.
+ * @method
+ * @memberof Popper.Utils
+ * @param {Array} modifiers - list of modifiers
+ * @param {String} requestingName - name of requesting modifier
+ * @param {String} requestedName - name of requested modifier
+ * @returns {Boolean}
+ */
+function isModifierRequired(modifiers, requestingName, requestedName) {
+  var requesting = find(modifiers, function (_ref) {
+    var name = _ref.name;
+    return name === requestingName;
+  });
+
+  var isRequired = !!requesting && modifiers.some(function (modifier) {
+    return modifier.name === requestedName && modifier.enabled && modifier.order < requesting.order;
+  });
+
+  if (!isRequired) {
+    var _requesting = '`' + requestingName + '`';
+    var requested = '`' + requestedName + '`';
+    console.warn(requested + ' modifier is required by ' + _requesting + ' modifier in order to work, be 
sure to include it before ' + _requesting + '!');
+  }
+  return isRequired;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function arrow(data, options) {
+  // arrow depends on keepTogether in order to work
+  if (!isModifierRequired(data.instance.modifiers, 'arrow', 'keepTogether')) {
+    return data;
+  }
+
+  var arrowElement = options.element;
+
+  // if arrowElement is a string, suppose it's a CSS selector
+  if (typeof arrowElement === 'string') {
+    arrowElement = data.instance.popper.querySelector(arrowElement);
+
+    // if arrowElement is not found, don't run the modifier
+    if (!arrowElement) {
+      return data;
+    }
+  } else {
+    // if the arrowElement isn't a query selector we must check that the
+    // provided DOM node is child of its popper node
+    if (!data.instance.popper.contains(arrowElement)) {
+      console.warn('WARNING: `arrow.element` must be child of its popper element!');
+      return data;
+    }
+  }
+
+  var placement = data.placement.split('-')[0];
+  var _data$offsets = data.offsets,
+      popper = _data$offsets.popper,
+      reference = _data$offsets.reference;
+
+  var isVertical = ['left', 'right'].indexOf(placement) !== -1;
+
+  var len = isVertical ? 'height' : 'width';
+  var sideCapitalized = isVertical ? 'Top' : 'Left';
+  var side = sideCapitalized.toLowerCase();
+  var altSide = isVertical ? 'left' : 'top';
+  var opSide = isVertical ? 'bottom' : 'right';
+  var arrowElementSize = getOuterSizes(arrowElement)[len];
+
+  //
+  // extends keepTogether behavior making sure the popper and its
+  // reference have enough pixels in conjuction
+  //
+
+  // top/left side
+  if (reference[opSide] - arrowElementSize < popper[side]) {
+    data.offsets.popper[side] -= popper[side] - (reference[opSide] - arrowElementSize);
+  }
+  // bottom/right side
+  if (reference[side] + arrowElementSize > popper[opSide]) {
+    data.offsets.popper[side] += reference[side] + arrowElementSize - popper[opSide];
+  }
+
+  // compute center of the popper
+  var center = reference[side] + reference[len] / 2 - arrowElementSize / 2;
+
+  // Compute the sideValue using the updated popper offsets
+  // take popper margin in account because we don't have this info available
+  var popperMarginSide = getStyleComputedProperty(data.instance.popper, 'margin' + 
sideCapitalized).replace('px', '');
+  var sideValue = center - getClientRect(data.offsets.popper)[side] - popperMarginSide;
+
+  // prevent arrowElement from being placed not contiguously to its popper
+  sideValue = Math.max(Math.min(popper[len] - arrowElementSize, sideValue), 0);
+
+  data.arrowElement = arrowElement;
+  data.offsets.arrow = {};
+  data.offsets.arrow[side] = Math.round(sideValue);
+  data.offsets.arrow[altSide] = ''; // make sure to unset any eventual altSide value from the DOM node
+
+  return data;
+}
+
+/**
+ * Get the opposite placement variation of the given one
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} placement variation
+ * @returns {String} flipped placement variation
+ */
+function getOppositeVariation(variation) {
+  if (variation === 'end') {
+    return 'start';
+  } else if (variation === 'start') {
+    return 'end';
+  }
+  return variation;
+}
+
+/**
+ * List of accepted placements to use as values of the `placement` option.<br />
+ * Valid placements are:
+ * - `auto`
+ * - `top`
+ * - `right`
+ * - `bottom`
+ * - `left`
+ *
+ * Each placement can have a variation from this list:
+ * - `-start`
+ * - `-end`
+ *
+ * Variations are interpreted easily if you think of them as the left to right
+ * written languages. Horizontally (`top` and `bottom`), `start` is left and `end`
+ * is right.<br />
+ * Vertically (`left` and `right`), `start` is top and `end` is bottom.
+ *
+ * Some valid examples are:
+ * - `top-end` (on top of reference, right aligned)
+ * - `right-start` (on right of reference, top aligned)
+ * - `bottom` (on bottom, centered)
+ * - `auto-right` (on the side with more space available, alignment depends by placement)
+ *
+ * @static
+ * @type {Array}
+ * @enum {String}
+ * @readonly
+ * @method placements
+ * @memberof Popper
+ */
+var placements = ['auto-start', 'auto', 'auto-end', 'top-start', 'top', 'top-end', 'right-start', 'right', 
'right-end', 'bottom-end', 'bottom', 'bottom-start', 'left-end', 'left', 'left-start'];
+
+// Get rid of `auto` `auto-start` and `auto-end`
+var validPlacements = placements.slice(3);
+
+/**
+ * Given an initial placement, returns all the subsequent placements
+ * clockwise (or counter-clockwise).
+ *
+ * @method
+ * @memberof Popper.Utils
+ * @argument {String} placement - A valid placement (it accepts variations)
+ * @argument {Boolean} counter - Set to true to walk the placements counterclockwise
+ * @returns {Array} placements including their variations
+ */
+function clockwise(placement) {
+  var counter = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
+
+  var index = validPlacements.indexOf(placement);
+  var arr = validPlacements.slice(index + 1).concat(validPlacements.slice(0, index));
+  return counter ? arr.reverse() : arr;
+}
+
+var BEHAVIORS = {
+  FLIP: 'flip',
+  CLOCKWISE: 'clockwise',
+  COUNTERCLOCKWISE: 'counterclockwise'
+};
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function flip(data, options) {
+  // if `inner` modifier is enabled, we can't use the `flip` modifier
+  if (isModifierEnabled(data.instance.modifiers, 'inner')) {
+    return data;
+  }
+
+  if (data.flipped && data.placement === data.originalPlacement) {
+    // seems like flip is trying to loop, probably there's not enough space on any of the flippable sides
+    return data;
+  }
+
+  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, 
options.boundariesElement);
+
+  var placement = data.placement.split('-')[0];
+  var placementOpposite = getOppositePlacement(placement);
+  var variation = data.placement.split('-')[1] || '';
+
+  var flipOrder = [];
+
+  switch (options.behavior) {
+    case BEHAVIORS.FLIP:
+      flipOrder = [placement, placementOpposite];
+      break;
+    case BEHAVIORS.CLOCKWISE:
+      flipOrder = clockwise(placement);
+      break;
+    case BEHAVIORS.COUNTERCLOCKWISE:
+      flipOrder = clockwise(placement, true);
+      break;
+    default:
+      flipOrder = options.behavior;
+  }
+
+  flipOrder.forEach(function (step, index) {
+    if (placement !== step || flipOrder.length === index + 1) {
+      return data;
+    }
+
+    placement = data.placement.split('-')[0];
+    placementOpposite = getOppositePlacement(placement);
+
+    var popperOffsets = data.offsets.popper;
+    var refOffsets = data.offsets.reference;
+
+    // using floor because the reference offsets may contain decimals we are not going to consider here
+    var floor = Math.floor;
+    var overlapsRef = placement === 'left' && floor(popperOffsets.right) > floor(refOffsets.left) || 
placement === 'right' && floor(popperOffsets.left) < floor(refOffsets.right) || placement === 'top' && 
floor(popperOffsets.bottom) > floor(refOffsets.top) || placement === 'bottom' && floor(popperOffsets.top) < 
floor(refOffsets.bottom);
+
+    var overflowsLeft = floor(popperOffsets.left) < floor(boundaries.left);
+    var overflowsRight = floor(popperOffsets.right) > floor(boundaries.right);
+    var overflowsTop = floor(popperOffsets.top) < floor(boundaries.top);
+    var overflowsBottom = floor(popperOffsets.bottom) > floor(boundaries.bottom);
+
+    var overflowsBoundaries = placement === 'left' && overflowsLeft || placement === 'right' && 
overflowsRight || placement === 'top' && overflowsTop || placement === 'bottom' && overflowsBottom;
+
+    // flip the variation if required
+    var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
+    var flippedVariation = !!options.flipVariations && (isVertical && variation === 'start' && overflowsLeft 
|| isVertical && variation === 'end' && overflowsRight || !isVertical && variation === 'start' && 
overflowsTop || !isVertical && variation === 'end' && overflowsBottom);
+
+    if (overlapsRef || overflowsBoundaries || flippedVariation) {
+      // this boolean to detect any flip loop
+      data.flipped = true;
+
+      if (overlapsRef || overflowsBoundaries) {
+        placement = flipOrder[index + 1];
+      }
+
+      if (flippedVariation) {
+        variation = getOppositeVariation(variation);
+      }
+
+      data.placement = placement + (variation ? '-' + variation : '');
+
+      // this object contains `position`, we want to preserve it along with
+      // any additional property we may add in the future
+      data.offsets.popper = _extends({}, data.offsets.popper, getPopperOffsets(data.instance.popper, 
data.offsets.reference, data.placement));
+
+      data = runModifiers(data.instance.modifiers, data, 'flip');
+    }
+  });
+  return data;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function keepTogether(data) {
+  var _data$offsets = data.offsets,
+      popper = _data$offsets.popper,
+      reference = _data$offsets.reference;
+
+  var placement = data.placement.split('-')[0];
+  var floor = Math.floor;
+  var isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
+  var side = isVertical ? 'right' : 'bottom';
+  var opSide = isVertical ? 'left' : 'top';
+  var measurement = isVertical ? 'width' : 'height';
+
+  if (popper[side] < floor(reference[opSide])) {
+    data.offsets.popper[opSide] = floor(reference[opSide]) - popper[measurement];
+  }
+  if (popper[opSide] > floor(reference[side])) {
+    data.offsets.popper[opSide] = floor(reference[side]);
+  }
+
+  return data;
+}
+
+/**
+ * Converts a string containing value + unit into a px value number
+ * @function
+ * @memberof {modifiers~offset}
+ * @private
+ * @argument {String} str - Value + unit string
+ * @argument {String} measurement - `height` or `width`
+ * @argument {Object} popperOffsets
+ * @argument {Object} referenceOffsets
+ * @returns {Number|String}
+ * Value in pixels, or original string if no values were extracted
+ */
+function toValue(str, measurement, popperOffsets, referenceOffsets) {
+  // separate value from unit
+  var split = str.match(/((?:\-|\+)?\d*\.?\d*)(.*)/);
+  var value = +split[1];
+  var unit = split[2];
+
+  // If it's not a number it's an operator, I guess
+  if (!value) {
+    return str;
+  }
+
+  if (unit.indexOf('%') === 0) {
+    var element = void 0;
+    switch (unit) {
+      case '%p':
+        element = popperOffsets;
+        break;
+      case '%':
+      case '%r':
+      default:
+        element = referenceOffsets;
+    }
+
+    var rect = getClientRect(element);
+    return rect[measurement] / 100 * value;
+  } else if (unit === 'vh' || unit === 'vw') {
+    // if is a vh or vw, we calculate the size based on the viewport
+    var size = void 0;
+    if (unit === 'vh') {
+      size = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
+    } else {
+      size = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
+    }
+    return size / 100 * value;
+  } else {
+    // if is an explicit pixel unit, we get rid of the unit and keep the value
+    // if is an implicit unit, it's px, and we return just the value
+    return value;
+  }
+}
+
+/**
+ * Parse an `offset` string to extrapolate `x` and `y` numeric offsets.
+ * @function
+ * @memberof {modifiers~offset}
+ * @private
+ * @argument {String} offset
+ * @argument {Object} popperOffsets
+ * @argument {Object} referenceOffsets
+ * @argument {String} basePlacement
+ * @returns {Array} a two cells array with x and y offsets in numbers
+ */
+function parseOffset(offset, popperOffsets, referenceOffsets, basePlacement) {
+  var offsets = [0, 0];
+
+  // Use height if placement is left or right and index is 0 otherwise use width
+  // in this way the first offset will use an axis and the second one
+  // will use the other one
+  var useHeight = ['right', 'left'].indexOf(basePlacement) !== -1;
+
+  // Split the offset string to obtain a list of values and operands
+  // The regex addresses values with the plus or minus sign in front (+10, -20, etc)
+  var fragments = offset.split(/(\+|\-)/).map(function (frag) {
+    return frag.trim();
+  });
+
+  // Detect if the offset string contains a pair of values or a single one
+  // they could be separated by comma or space
+  var divider = fragments.indexOf(find(fragments, function (frag) {
+    return frag.search(/,|\s/) !== -1;
+  }));
+
+  if (fragments[divider] && fragments[divider].indexOf(',') === -1) {
+    console.warn('Offsets separated by white space(s) are deprecated, use a comma (,) instead.');
+  }
+
+  // If divider is found, we divide the list of values and operands to divide
+  // them by ofset X and Y.
+  var splitRegex = /\s*,\s*|\s+/;
+  var ops = divider !== -1 ? [fragments.slice(0, divider).concat([fragments[divider].split(splitRegex)[0]]), 
[fragments[divider].split(splitRegex)[1]].concat(fragments.slice(divider + 1))] : [fragments];
+
+  // Convert the values with units to absolute pixels to allow our computations
+  ops = ops.map(function (op, index) {
+    // Most of the units rely on the orientation of the popper
+    var measurement = (index === 1 ? !useHeight : useHeight) ? 'height' : 'width';
+    var mergeWithPrevious = false;
+    return op
+    // This aggregates any `+` or `-` sign that aren't considered operators
+    // e.g.: 10 + +5 => [10, +, +5]
+    .reduce(function (a, b) {
+      if (a[a.length - 1] === '' && ['+', '-'].indexOf(b) !== -1) {
+        a[a.length - 1] = b;
+        mergeWithPrevious = true;
+        return a;
+      } else if (mergeWithPrevious) {
+        a[a.length - 1] += b;
+        mergeWithPrevious = false;
+        return a;
+      } else {
+        return a.concat(b);
+      }
+    }, [])
+    // Here we convert the string values into number values (in px)
+    .map(function (str) {
+      return toValue(str, measurement, popperOffsets, referenceOffsets);
+    });
+  });
+
+  // Loop trough the offsets arrays and execute the operations
+  ops.forEach(function (op, index) {
+    op.forEach(function (frag, index2) {
+      if (isNumeric(frag)) {
+        offsets[index] += frag * (op[index2 - 1] === '-' ? -1 : 1);
+      }
+    });
+  });
+  return offsets;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @argument {Number|String} options.offset=0
+ * The offset value as described in the modifier description
+ * @returns {Object} The data object, properly modified
+ */
+function offset(data, _ref) {
+  var offset = _ref.offset;
+  var placement = data.placement,
+      _data$offsets = data.offsets,
+      popper = _data$offsets.popper,
+      reference = _data$offsets.reference;
+
+  var basePlacement = placement.split('-')[0];
+
+  var offsets = void 0;
+  if (isNumeric(+offset)) {
+    offsets = [+offset, 0];
+  } else {
+    offsets = parseOffset(offset, popper, reference, basePlacement);
+  }
+
+  if (basePlacement === 'left') {
+    popper.top += offsets[0];
+    popper.left -= offsets[1];
+  } else if (basePlacement === 'right') {
+    popper.top += offsets[0];
+    popper.left += offsets[1];
+  } else if (basePlacement === 'top') {
+    popper.left += offsets[0];
+    popper.top -= offsets[1];
+  } else if (basePlacement === 'bottom') {
+    popper.left += offsets[0];
+    popper.top += offsets[1];
+  }
+
+  data.popper = popper;
+  return data;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function preventOverflow(data, options) {
+  var boundariesElement = options.boundariesElement || getOffsetParent(data.instance.popper);
+
+  // If offsetParent is the reference element, we really want to
+  // go one step up and use the next offsetParent as reference to
+  // avoid to make this modifier completely useless and look like broken
+  if (data.instance.reference === boundariesElement) {
+    boundariesElement = getOffsetParent(boundariesElement);
+  }
+
+  var boundaries = getBoundaries(data.instance.popper, data.instance.reference, options.padding, 
boundariesElement);
+  options.boundaries = boundaries;
+
+  var order = options.priority;
+  var popper = data.offsets.popper;
+
+  var check = {
+    primary: function primary(placement) {
+      var value = popper[placement];
+      if (popper[placement] < boundaries[placement] && !options.escapeWithReference) {
+        value = Math.max(popper[placement], boundaries[placement]);
+      }
+      return defineProperty({}, placement, value);
+    },
+    secondary: function secondary(placement) {
+      var mainSide = placement === 'right' ? 'left' : 'top';
+      var value = popper[mainSide];
+      if (popper[placement] > boundaries[placement] && !options.escapeWithReference) {
+        value = Math.min(popper[mainSide], boundaries[placement] - (placement === 'right' ? popper.width : 
popper.height));
+      }
+      return defineProperty({}, mainSide, value);
+    }
+  };
+
+  order.forEach(function (placement) {
+    var side = ['left', 'top'].indexOf(placement) !== -1 ? 'primary' : 'secondary';
+    popper = _extends({}, popper, check[side](placement));
+  });
+
+  data.offsets.popper = popper;
+
+  return data;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function shift(data) {
+  var placement = data.placement;
+  var basePlacement = placement.split('-')[0];
+  var shiftvariation = placement.split('-')[1];
+
+  // if shift shiftvariation is specified, run the modifier
+  if (shiftvariation) {
+    var _data$offsets = data.offsets,
+        reference = _data$offsets.reference,
+        popper = _data$offsets.popper;
+
+    var isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
+    var side = isVertical ? 'left' : 'top';
+    var measurement = isVertical ? 'width' : 'height';
+
+    var shiftOffsets = {
+      start: defineProperty({}, side, reference[side]),
+      end: defineProperty({}, side, reference[side] + reference[measurement] - popper[measurement])
+    };
+
+    data.offsets.popper = _extends({}, popper, shiftOffsets[shiftvariation]);
+  }
+
+  return data;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by update method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function hide(data) {
+  if (!isModifierRequired(data.instance.modifiers, 'hide', 'preventOverflow')) {
+    return data;
+  }
+
+  var refRect = data.offsets.reference;
+  var bound = find(data.instance.modifiers, function (modifier) {
+    return modifier.name === 'preventOverflow';
+  }).boundaries;
+
+  if (refRect.bottom < bound.top || refRect.left > bound.right || refRect.top > bound.bottom || 
refRect.right < bound.left) {
+    // Avoid unnecessary DOM access if visibility hasn't changed
+    if (data.hide === true) {
+      return data;
+    }
+
+    data.hide = true;
+    data.attributes['x-out-of-boundaries'] = '';
+  } else {
+    // Avoid unnecessary DOM access if visibility hasn't changed
+    if (data.hide === false) {
+      return data;
+    }
+
+    data.hide = false;
+    data.attributes['x-out-of-boundaries'] = false;
+  }
+
+  return data;
+}
+
+/**
+ * @function
+ * @memberof Modifiers
+ * @argument {Object} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {Object} The data object, properly modified
+ */
+function inner(data) {
+  var placement = data.placement;
+  var basePlacement = placement.split('-')[0];
+  var _data$offsets = data.offsets,
+      popper = _data$offsets.popper,
+      reference = _data$offsets.reference;
+
+  var isHoriz = ['left', 'right'].indexOf(basePlacement) !== -1;
+
+  var subtractLength = ['top', 'left'].indexOf(basePlacement) === -1;
+
+  popper[isHoriz ? 'left' : 'top'] = reference[basePlacement] - (subtractLength ? popper[isHoriz ? 'width' : 
'height'] : 0);
+
+  data.placement = getOppositePlacement(placement);
+  data.offsets.popper = getClientRect(popper);
+
+  return data;
+}
+
+/**
+ * Modifier function, each modifier can have a function of this type assigned
+ * to its `fn` property.<br />
+ * These functions will be called on each update, this means that you must
+ * make sure they are performant enough to avoid performance bottlenecks.
+ *
+ * @function ModifierFn
+ * @argument {dataObject} data - The data object generated by `update` method
+ * @argument {Object} options - Modifiers configuration and options
+ * @returns {dataObject} The data object, properly modified
+ */
+
+/**
+ * Modifiers are plugins used to alter the behavior of your poppers.<br />
+ * Popper.js uses a set of 9 modifiers to provide all the basic functionalities
+ * needed by the library.
+ *
+ * Usually you don't want to override the `order`, `fn` and `onLoad` props.
+ * All the other properties are configurations that could be tweaked.
+ * @namespace modifiers
+ */
+var modifiers = {
+  /**
+   * Modifier used to shift the popper on the start or end of its reference
+   * element.<br />
+   * It will read the variation of the `placement` property.<br />
+   * It can be one either `-end` or `-start`.
+   * @memberof modifiers
+   * @inner
+   */
+  shift: {
+    /** @prop {number} order=100 - Index used to define the order of execution */
+    order: 100,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: shift
+  },
+
+  /**
+   * The `offset` modifier can shift your popper on both its axis.
+   *
+   * It accepts the following units:
+   * - `px` or unitless, interpreted as pixels
+   * - `%` or `%r`, percentage relative to the length of the reference element
+   * - `%p`, percentage relative to the length of the popper element
+   * - `vw`, CSS viewport width unit
+   * - `vh`, CSS viewport height unit
+   *
+   * For length is intended the main axis relative to the placement of the popper.<br />
+   * This means that if the placement is `top` or `bottom`, the length will be the
+   * `width`. In case of `left` or `right`, it will be the height.
+   *
+   * You can provide a single value (as `Number` or `String`), or a pair of values
+   * as `String` divided by a comma or one (or more) white spaces.<br />
+   * The latter is a deprecated method because it leads to confusion and will be
+   * removed in v2.<br />
+   * Additionally, it accepts additions and subtractions between different units.
+   * Note that multiplications and divisions aren't supported.
+   *
+   * Valid examples are:
+   * ```
+   * 10
+   * '10%'
+   * '10, 10'
+   * '10%, 10'
+   * '10 + 10%'
+   * '10 - 5vh + 3%'
+   * '-10px + 5vh, 5px - 6%'
+   * ```
+   * > **NB**: If you desire to apply offsets to your poppers in a way that may make them overlap
+   * > with their reference element, unfortunately, you will have to disable the `flip` modifier.
+   * > More on this [reading this issue](https://github.com/FezVrasta/popper.js/issues/373)
+   *
+   * @memberof modifiers
+   * @inner
+   */
+  offset: {
+    /** @prop {number} order=200 - Index used to define the order of execution */
+    order: 200,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: offset,
+    /** @prop {Number|String} offset=0
+     * The offset value as described in the modifier description
+     */
+    offset: 0
+  },
+
+  /**
+   * Modifier used to prevent the popper from being positioned outside the boundary.
+   *
+   * An scenario exists where the reference itself is not within the boundaries.<br />
+   * We can say it has "escaped the boundaries" — or just "escaped".<br />
+   * In this case we need to decide whether the popper should either:
+   *
+   * - detach from the reference and remain "trapped" in the boundaries, or
+   * - if it should ignore the boundary and "escape with its reference"
+   *
+   * When `escapeWithReference` is set to`true` and reference is completely
+   * outside its boundaries, the popper will overflow (or completely leave)
+   * the boundaries in order to remain attached to the edge of the reference.
+   *
+   * @memberof modifiers
+   * @inner
+   */
+  preventOverflow: {
+    /** @prop {number} order=300 - Index used to define the order of execution */
+    order: 300,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: preventOverflow,
+    /**
+     * @prop {Array} [priority=['left','right','top','bottom']]
+     * Popper will try to prevent overflow following these priorities by default,
+     * then, it could overflow on the left and on top of the `boundariesElement`
+     */
+    priority: ['left', 'right', 'top', 'bottom'],
+    /**
+     * @prop {number} padding=5
+     * Amount of pixel used to define a minimum distance between the boundaries
+     * and the popper this makes sure the popper has always a little padding
+     * between the edges of its container
+     */
+    padding: 5,
+    /**
+     * @prop {String|HTMLElement} boundariesElement='scrollParent'
+     * Boundaries used by the modifier, can be `scrollParent`, `window`,
+     * `viewport` or any DOM element.
+     */
+    boundariesElement: 'scrollParent'
+  },
+
+  /**
+   * Modifier used to make sure the reference and its popper stay near eachothers
+   * without leaving any gap between the two. Expecially useful when the arrow is
+   * enabled and you want to assure it to point to its reference element.
+   * It cares only about the first axis, you can still have poppers with margin
+   * between the popper and its reference element.
+   * @memberof modifiers
+   * @inner
+   */
+  keepTogether: {
+    /** @prop {number} order=400 - Index used to define the order of execution */
+    order: 400,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: keepTogether
+  },
+
+  /**
+   * This modifier is used to move the `arrowElement` of the popper to make
+   * sure it is positioned between the reference element and its popper element.
+   * It will read the outer size of the `arrowElement` node to detect how many
+   * pixels of conjuction are needed.
+   *
+   * It has no effect if no `arrowElement` is provided.
+   * @memberof modifiers
+   * @inner
+   */
+  arrow: {
+    /** @prop {number} order=500 - Index used to define the order of execution */
+    order: 500,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: arrow,
+    /** @prop {String|HTMLElement} element='[x-arrow]' - Selector or node used as arrow */
+    element: '[x-arrow]'
+  },
+
+  /**
+   * Modifier used to flip the popper's placement when it starts to overlap its
+   * reference element.
+   *
+   * Requires the `preventOverflow` modifier before it in order to work.
+   *
+   * **NOTE:** this modifier will interrupt the current update cycle and will
+   * restart it if it detects the need to flip the placement.
+   * @memberof modifiers
+   * @inner
+   */
+  flip: {
+    /** @prop {number} order=600 - Index used to define the order of execution */
+    order: 600,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: flip,
+    /**
+     * @prop {String|Array} behavior='flip'
+     * The behavior used to change the popper's placement. It can be one of
+     * `flip`, `clockwise`, `counterclockwise` or an array with a list of valid
+     * placements (with optional variations).
+     */
+    behavior: 'flip',
+    /**
+     * @prop {number} padding=5
+     * The popper will flip if it hits the edges of the `boundariesElement`
+     */
+    padding: 5,
+    /**
+     * @prop {String|HTMLElement} boundariesElement='viewport'
+     * The element which will define the boundaries of the popper position,
+     * the popper will never be placed outside of the defined boundaries
+     * (except if keepTogether is enabled)
+     */
+    boundariesElement: 'viewport'
+  },
+
+  /**
+   * Modifier used to make the popper flow toward the inner of the reference element.
+   * By default, when this modifier is disabled, the popper will be placed outside
+   * the reference element.
+   * @memberof modifiers
+   * @inner
+   */
+  inner: {
+    /** @prop {number} order=700 - Index used to define the order of execution */
+    order: 700,
+    /** @prop {Boolean} enabled=false - Whether the modifier is enabled or not */
+    enabled: false,
+    /** @prop {ModifierFn} */
+    fn: inner
+  },
+
+  /**
+   * Modifier used to hide the popper when its reference element is outside of the
+   * popper boundaries. It will set a `x-out-of-boundaries` attribute which can
+   * be used to hide with a CSS selector the popper when its reference is
+   * out of boundaries.
+   *
+   * Requires the `preventOverflow` modifier before it in order to work.
+   * @memberof modifiers
+   * @inner
+   */
+  hide: {
+    /** @prop {number} order=800 - Index used to define the order of execution */
+    order: 800,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: hide
+  },
+
+  /**
+   * Computes the style that will be applied to the popper element to gets
+   * properly positioned.
+   *
+   * Note that this modifier will not touch the DOM, it just prepares the styles
+   * so that `applyStyle` modifier can apply it. This separation is useful
+   * in case you need to replace `applyStyle` with a custom implementation.
+   *
+   * This modifier has `850` as `order` value to maintain backward compatibility
+   * with previous versions of Popper.js. Expect the modifiers ordering method
+   * to change in future major versions of the library.
+   *
+   * @memberof modifiers
+   * @inner
+   */
+  computeStyle: {
+    /** @prop {number} order=850 - Index used to define the order of execution */
+    order: 850,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: computeStyle,
+    /**
+     * @prop {Boolean} gpuAcceleration=true
+     * If true, it uses the CSS 3d transformation to position the popper.
+     * Otherwise, it will use the `top` and `left` properties.
+     */
+    gpuAcceleration: true,
+    /**
+     * @prop {string} [x='bottom']
+     * Where to anchor the X axis (`bottom` or `top`). AKA X offset origin.
+     * Change this if your popper should grow in a direction different from `bottom`
+     */
+    x: 'bottom',
+    /**
+     * @prop {string} [x='left']
+     * Where to anchor the Y axis (`left` or `right`). AKA Y offset origin.
+     * Change this if your popper should grow in a direction different from `right`
+     */
+    y: 'right'
+  },
+
+  /**
+   * Applies the computed styles to the popper element.
+   *
+   * All the DOM manipulations are limited to this modifier. This is useful in case
+   * you want to integrate Popper.js inside a framework or view library and you
+   * want to delegate all the DOM manipulations to it.
+   *
+   * Note that if you disable this modifier, you must make sure the popper element
+   * has its position set to `absolute` before Popper.js can do its work!
+   *
+   * Just disable this modifier and define you own to achieve the desired effect.
+   *
+   * @memberof modifiers
+   * @inner
+   */
+  applyStyle: {
+    /** @prop {number} order=900 - Index used to define the order of execution */
+    order: 900,
+    /** @prop {Boolean} enabled=true - Whether the modifier is enabled or not */
+    enabled: true,
+    /** @prop {ModifierFn} */
+    fn: applyStyle,
+    /** @prop {Function} */
+    onLoad: applyStyleOnLoad,
+    /**
+     * @deprecated since version 1.10.0, the property moved to `computeStyle` modifier
+     * @prop {Boolean} gpuAcceleration=true
+     * If true, it uses the CSS 3d transformation to position the popper.
+     * Otherwise, it will use the `top` and `left` properties.
+     */
+    gpuAcceleration: undefined
+  }
+};
+
+/**
+ * The `dataObject` is an object containing all the informations used by Popper.js
+ * this object get passed to modifiers and to the `onCreate` and `onUpdate` callbacks.
+ * @name dataObject
+ * @property {Object} data.instance The Popper.js instance
+ * @property {String} data.placement Placement applied to popper
+ * @property {String} data.originalPlacement Placement originally defined on init
+ * @property {Boolean} data.flipped True if popper has been flipped by flip modifier
+ * @property {Boolean} data.hide True if the reference element is out of boundaries, useful to know when to 
hide the popper.
+ * @property {HTMLElement} data.arrowElement Node used as arrow by arrow modifier
+ * @property {Object} data.styles Any CSS property defined here will be applied to the popper, it expects 
the JavaScript nomenclature (eg. `marginBottom`)
+ * @property {Object} data.arrowStyles Any CSS property defined here will be applied to the popper arrow, it 
expects the JavaScript nomenclature (eg. `marginBottom`)
+ * @property {Object} data.boundaries Offsets of the popper boundaries
+ * @property {Object} data.offsets The measurements of popper, reference and arrow elements.
+ * @property {Object} data.offsets.popper `top`, `left`, `width`, `height` values
+ * @property {Object} data.offsets.reference `top`, `left`, `width`, `height` values
+ * @property {Object} data.offsets.arrow] `top` and `left` offsets, only one of them will be different from 0
+ */
+
+/**
+ * Default options provided to Popper.js constructor.<br />
+ * These can be overriden using the `options` argument of Popper.js.<br />
+ * To override an option, simply pass as 3rd argument an object with the same
+ * structure of this object, example:
+ * ```
+ * new Popper(ref, pop, {
+ *   modifiers: {
+ *     preventOverflow: { enabled: false }
+ *   }
+ * })
+ * ```
+ * @type {Object}
+ * @static
+ * @memberof Popper
+ */
+var Defaults = {
+  /**
+   * Popper's placement
+   * @prop {Popper.placements} placement='bottom'
+   */
+  placement: 'bottom',
+
+  /**
+   * Whether events (resize, scroll) are initially enabled
+   * @prop {Boolean} eventsEnabled=true
+   */
+  eventsEnabled: true,
+
+  /**
+   * Set to true if you want to automatically remove the popper when
+   * you call the `destroy` method.
+   * @prop {Boolean} removeOnDestroy=false
+   */
+  removeOnDestroy: false,
+
+  /**
+   * Callback called when the popper is created.<br />
+   * By default, is set to no-op.<br />
+   * Access Popper.js instance with `data.instance`.
+   * @prop {onCreate}
+   */
+  onCreate: function onCreate() {},
+
+  /**
+   * Callback called when the popper is updated, this callback is not called
+   * on the initialization/creation of the popper, but only on subsequent
+   * updates.<br />
+   * By default, is set to no-op.<br />
+   * Access Popper.js instance with `data.instance`.
+   * @prop {onUpdate}
+   */
+  onUpdate: function onUpdate() {},
+
+  /**
+   * List of modifiers used to modify the offsets before they are applied to the popper.
+   * They provide most of the functionalities of Popper.js
+   * @prop {modifiers}
+   */
+  modifiers: modifiers
+};
+
+/**
+ * @callback onCreate
+ * @param {dataObject} data
+ */
+
+/**
+ * @callback onUpdate
+ * @param {dataObject} data
+ */
+
+// Utils
+// Methods
+var Popper = function () {
+  /**
+   * Create a new Popper.js instance
+   * @class Popper
+   * @param {HTMLElement|referenceObject} reference - The reference element used to position the popper
+   * @param {HTMLElement} popper - The HTML element used as popper.
+   * @param {Object} options - Your custom options to override the ones defined in [Defaults](#defaults)
+   * @return {Object} instance - The generated Popper.js instance
+   */
+  function Popper(reference, popper) {
+    var _this = this;
+
+    var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
+    classCallCheck(this, Popper);
+
+    this.scheduleUpdate = function () {
+      return requestAnimationFrame(_this.update);
+    };
+
+    // make update() debounced, so that it only runs at most once-per-tick
+    this.update = debounce(this.update.bind(this));
+
+    // with {} we create a new object with the options inside it
+    this.options = _extends({}, Popper.Defaults, options);
+
+    // init state
+    this.state = {
+      isDestroyed: false,
+      isCreated: false,
+      scrollParents: []
+    };
+
+    // get reference and popper elements (allow jQuery wrappers)
+    this.reference = reference.jquery ? reference[0] : reference;
+    this.popper = popper.jquery ? popper[0] : popper;
+
+    // Deep merge modifiers options
+    this.options.modifiers = {};
+    Object.keys(_extends({}, Popper.Defaults.modifiers, options.modifiers)).forEach(function (name) {
+      _this.options.modifiers[name] = _extends({}, Popper.Defaults.modifiers[name] || {}, options.modifiers 
? options.modifiers[name] : {});
+    });
+
+    // Refactoring modifiers' list (Object => Array)
+    this.modifiers = Object.keys(this.options.modifiers).map(function (name) {
+      return _extends({
+        name: name
+      }, _this.options.modifiers[name]);
+    })
+    // sort the modifiers by order
+    .sort(function (a, b) {
+      return a.order - b.order;
+    });
+
+    // modifiers have the ability to execute arbitrary code when Popper.js get inited
+    // such code is executed in the same order of its modifier
+    // they could add new properties to their options configuration
+    // BE AWARE: don't add options to `options.modifiers.name` but to `modifierOptions`!
+    this.modifiers.forEach(function (modifierOptions) {
+      if (modifierOptions.enabled && isFunction(modifierOptions.onLoad)) {
+        modifierOptions.onLoad(_this.reference, _this.popper, _this.options, modifierOptions, _this.state);
+      }
+    });
+
+    // fire the first update to position the popper in the right place
+    this.update();
+
+    var eventsEnabled = this.options.eventsEnabled;
+    if (eventsEnabled) {
+      // setup event listeners, they will take care of update the position in specific situations
+      this.enableEventListeners();
+    }
+
+    this.state.eventsEnabled = eventsEnabled;
+  }
+
+  // We can't use class properties because they don't get listed in the
+  // class prototype and break stuff like Sinon stubs
+
+
+  createClass(Popper, [{
+    key: 'update',
+    value: function update$$1() {
+      return update.call(this);
+    }
+  }, {
+    key: 'destroy',
+    value: function destroy$$1() {
+      return destroy.call(this);
+    }
+  }, {
+    key: 'enableEventListeners',
+    value: function enableEventListeners$$1() {
+      return enableEventListeners.call(this);
+    }
+  }, {
+    key: 'disableEventListeners',
+    value: function disableEventListeners$$1() {
+      return disableEventListeners.call(this);
+    }
+
+    /**
+     * Schedule an update, it will run on the next UI update available
+     * @method scheduleUpdate
+     * @memberof Popper
+     */
+
+
+    /**
+     * Collection of utilities useful when writing custom modifiers.
+     * Starting from version 1.7, this method is available only if you
+     * include `popper-utils.js` before `popper.js`.
+     *
+     * **DEPRECATION**: This way to access PopperUtils is deprecated
+     * and will be removed in v2! Use the PopperUtils module directly instead.
+     * Due to the high instability of the methods contained in Utils, we can't
+     * guarantee them to follow semver. Use them at your own risk!
+     * @static
+     * @private
+     * @type {Object}
+     * @deprecated since version 1.8
+     * @member Utils
+     * @memberof Popper
+     */
+
+  }]);
+  return Popper;
+}();
+
+/**
+ * The `referenceObject` is an object that provides an interface compatible with Popper.js
+ * and lets you use it as replacement of a real DOM node.<br />
+ * You can use this method to position a popper relatively to a set of coordinates
+ * in case you don't have a DOM node to use as reference.
+ *
+ * ```
+ * new Popper(referenceObject, popperNode);
+ * ```
+ *
+ * NB: This feature isn't supported in Internet Explorer 10
+ * @name referenceObject
+ * @property {Function} data.getBoundingClientRect
+ * A function that returns a set of coordinates compatible with the native `getBoundingClientRect` method.
+ * @property {number} data.clientWidth
+ * An ES6 getter that will return the width of the virtual reference element.
+ * @property {number} data.clientHeight
+ * An ES6 getter that will return the height of the virtual reference element.
+ */
+
+
+Popper.Utils = (typeof window !== 'undefined' ? window : global).PopperUtils;
+Popper.placements = placements;
+Popper.Defaults = Defaults;
+
+return Popper;
+
+})));
+//# sourceMappingURL=popper.js.map
diff --git a/src/js/03-bootstrap-4.0.0-beta.2.js b/src/js/03-bootstrap-4.0.0-beta.2.js
new file mode 100644
index 0000000..630a9e0
--- /dev/null
+++ b/src/js/03-bootstrap-4.0.0-beta.2.js
@@ -0,0 +1,3850 @@
+/*!
+  * Bootstrap v4.0.0-beta.2 (https://getbootstrap.com)
+  * Copyright 2011-2017 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors)
+  * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+  */
+var bootstrap = (function (exports,$,Popper) {
+'use strict';
+
+$ = $ && $.hasOwnProperty('default') ? $['default'] : $;
+Popper = Popper && Popper.hasOwnProperty('default') ? Popper['default'] : Popper;
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): util.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Util = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Private TransitionEnd Helpers
+   * ------------------------------------------------------------------------
+   */
+  var transition = false;
+  var MAX_UID = 1000000;
+  var TransitionEndEvent = {
+    WebkitTransition: 'webkitTransitionEnd',
+    MozTransition: 'transitionend',
+    OTransition: 'oTransitionEnd otransitionend',
+    transition: 'transitionend' // shoutout AngusCroll (https://goo.gl/pxwQGp)
+
+  };
+
+  function toType(obj) {
+    return {}.toString.call(obj).match(/\s([a-zA-Z]+)/)[1].toLowerCase();
+  }
+
+  function getSpecialTransitionEndEvent() {
+    return {
+      bindType: transition.end,
+      delegateType: transition.end,
+      handle: function handle(event) {
+        if ($(event.target).is(this)) {
+          return event.handleObj.handler.apply(this, arguments); // eslint-disable-line prefer-rest-params
+        }
+
+        return undefined; // eslint-disable-line no-undefined
+      }
+    };
+  }
+
+  function transitionEndTest() {
+    if (window.QUnit) {
+      return false;
+    }
+
+    var el = document.createElement('bootstrap');
+
+    for (var name in TransitionEndEvent) {
+      if (typeof el.style[name] !== 'undefined') {
+        return {
+          end: TransitionEndEvent[name]
+        };
+      }
+    }
+
+    return false;
+  }
+
+  function transitionEndEmulator(duration) {
+    var _this = this;
+
+    var called = false;
+    $(this).one(Util.TRANSITION_END, function () {
+      called = true;
+    });
+    setTimeout(function () {
+      if (!called) {
+        Util.triggerTransitionEnd(_this);
+      }
+    }, duration);
+    return this;
+  }
+
+  function setTransitionEndSupport() {
+    transition = transitionEndTest();
+    $.fn.emulateTransitionEnd = transitionEndEmulator;
+
+    if (Util.supportsTransitionEnd()) {
+      $.event.special[Util.TRANSITION_END] = getSpecialTransitionEndEvent();
+    }
+  }
+  /**
+   * --------------------------------------------------------------------------
+   * Public Util Api
+   * --------------------------------------------------------------------------
+   */
+
+
+  var Util = {
+    TRANSITION_END: 'bsTransitionEnd',
+    getUID: function getUID(prefix) {
+      do {
+        // eslint-disable-next-line no-bitwise
+        prefix += ~~(Math.random() * MAX_UID); // "~~" acts like a faster Math.floor() here
+      } while (document.getElementById(prefix));
+
+      return prefix;
+    },
+    getSelectorFromElement: function getSelectorFromElement(element) {
+      var selector = element.getAttribute('data-target');
+
+      if (!selector || selector === '#') {
+        selector = element.getAttribute('href') || '';
+      }
+
+      try {
+        var $selector = $(document).find(selector);
+        return $selector.length > 0 ? selector : null;
+      } catch (error) {
+        return null;
+      }
+    },
+    reflow: function reflow(element) {
+      return element.offsetHeight;
+    },
+    triggerTransitionEnd: function triggerTransitionEnd(element) {
+      $(element).trigger(transition.end);
+    },
+    supportsTransitionEnd: function supportsTransitionEnd() {
+      return Boolean(transition);
+    },
+    isElement: function isElement(obj) {
+      return (obj[0] || obj).nodeType;
+    },
+    typeCheckConfig: function typeCheckConfig(componentName, config, configTypes) {
+      for (var property in configTypes) {
+        if (Object.prototype.hasOwnProperty.call(configTypes, property)) {
+          var expectedTypes = configTypes[property];
+          var value = config[property];
+          var valueType = value && Util.isElement(value) ? 'element' : toType(value);
+
+          if (!new RegExp(expectedTypes).test(valueType)) {
+            throw new Error(componentName.toUpperCase() + ": " + ("Option \"" + property + "\" provided type 
\"" + valueType + "\" ") + ("but expected type \"" + expectedTypes + "\"."));
+          }
+        }
+      }
+    }
+  };
+  setTransitionEndSupport();
+  return Util;
+}($);
+
+function _defineProperties(target, props) {
+  for (var i = 0; i < props.length; i++) {
+    var descriptor = props[i];
+    descriptor.enumerable = descriptor.enumerable || false;
+    descriptor.configurable = true;
+    if ("value" in descriptor) descriptor.writable = true;
+    Object.defineProperty(target, descriptor.key, descriptor);
+  }
+}
+
+function _createClass(Constructor, protoProps, staticProps) {
+  if (protoProps) _defineProperties(Constructor.prototype, protoProps);
+  if (staticProps) _defineProperties(Constructor, staticProps);
+  return Constructor;
+}
+
+var createClass = _createClass;
+
+function _inheritsLoose(subClass, superClass) {
+  subClass.prototype = Object.create(superClass.prototype);
+  subClass.prototype.constructor = subClass;
+  subClass.__proto__ = superClass;
+}
+
+var inheritsLoose = _inheritsLoose;
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): alert.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Alert = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'alert';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.alert';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+  var Selector = {
+    DISMISS: '[data-dismiss="alert"]'
+  };
+  var Event = {
+    CLOSE: "close" + EVENT_KEY,
+    CLOSED: "closed" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    ALERT: 'alert',
+    FADE: 'fade',
+    SHOW: 'show'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Alert =
+  /*#__PURE__*/
+  function () {
+    function Alert(element) {
+      this._element = element;
+    } // getters
+
+
+    var _proto = Alert.prototype;
+
+    // public
+    _proto.close = function close(element) {
+      element = element || this._element;
+
+      var rootElement = this._getRootElement(element);
+
+      var customEvent = this._triggerCloseEvent(rootElement);
+
+      if (customEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      this._removeElement(rootElement);
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      this._element = null;
+    }; // private
+
+
+    _proto._getRootElement = function _getRootElement(element) {
+      var selector = Util.getSelectorFromElement(element);
+      var parent = false;
+
+      if (selector) {
+        parent = $(selector)[0];
+      }
+
+      if (!parent) {
+        parent = $(element).closest("." + ClassName.ALERT)[0];
+      }
+
+      return parent;
+    };
+
+    _proto._triggerCloseEvent = function _triggerCloseEvent(element) {
+      var closeEvent = $.Event(Event.CLOSE);
+      $(element).trigger(closeEvent);
+      return closeEvent;
+    };
+
+    _proto._removeElement = function _removeElement(element) {
+      var _this = this;
+
+      $(element).removeClass(ClassName.SHOW);
+
+      if (!Util.supportsTransitionEnd() || !$(element).hasClass(ClassName.FADE)) {
+        this._destroyElement(element);
+
+        return;
+      }
+
+      $(element).one(Util.TRANSITION_END, function (event) {
+        return _this._destroyElement(element, event);
+      }).emulateTransitionEnd(TRANSITION_DURATION);
+    };
+
+    _proto._destroyElement = function _destroyElement(element) {
+      $(element).detach().trigger(Event.CLOSED).remove();
+    }; // static
+
+
+    Alert._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var $element = $(this);
+        var data = $element.data(DATA_KEY);
+
+        if (!data) {
+          data = new Alert(this);
+          $element.data(DATA_KEY, data);
+        }
+
+        if (config === 'close') {
+          data[config](this);
+        }
+      });
+    };
+
+    Alert._handleDismiss = function _handleDismiss(alertInstance) {
+      return function (event) {
+        if (event) {
+          event.preventDefault();
+        }
+
+        alertInstance.close(this);
+      };
+    };
+
+    createClass(Alert, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }]);
+    return Alert;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DISMISS, Alert._handleDismiss(new Alert()));
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Alert._jQueryInterface;
+  $.fn[NAME].Constructor = Alert;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Alert._jQueryInterface;
+  };
+
+  return Alert;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): button.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Button = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'button';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.button';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var ClassName = {
+    ACTIVE: 'active',
+    BUTTON: 'btn',
+    FOCUS: 'focus'
+  };
+  var Selector = {
+    DATA_TOGGLE_CARROT: '[data-toggle^="button"]',
+    DATA_TOGGLE: '[data-toggle="buttons"]',
+    INPUT: 'input',
+    ACTIVE: '.active',
+    BUTTON: '.btn'
+  };
+  var Event = {
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY,
+    FOCUS_BLUR_DATA_API: "focus" + EVENT_KEY + DATA_API_KEY + " " + ("blur" + EVENT_KEY + DATA_API_KEY)
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Button =
+  /*#__PURE__*/
+  function () {
+    function Button(element) {
+      this._element = element;
+    } // getters
+
+
+    var _proto = Button.prototype;
+
+    // public
+    _proto.toggle = function toggle() {
+      var triggerChangeEvent = true;
+      var addAriaPressed = true;
+      var rootElement = $(this._element).closest(Selector.DATA_TOGGLE)[0];
+
+      if (rootElement) {
+        var input = $(this._element).find(Selector.INPUT)[0];
+
+        if (input) {
+          if (input.type === 'radio') {
+            if (input.checked && $(this._element).hasClass(ClassName.ACTIVE)) {
+              triggerChangeEvent = false;
+            } else {
+              var activeElement = $(rootElement).find(Selector.ACTIVE)[0];
+
+              if (activeElement) {
+                $(activeElement).removeClass(ClassName.ACTIVE);
+              }
+            }
+          }
+
+          if (triggerChangeEvent) {
+            if (input.hasAttribute('disabled') || rootElement.hasAttribute('disabled') || 
input.classList.contains('disabled') || rootElement.classList.contains('disabled')) {
+              return;
+            }
+
+            input.checked = !$(this._element).hasClass(ClassName.ACTIVE);
+            $(input).trigger('change');
+          }
+
+          input.focus();
+          addAriaPressed = false;
+        }
+      }
+
+      if (addAriaPressed) {
+        this._element.setAttribute('aria-pressed', !$(this._element).hasClass(ClassName.ACTIVE));
+      }
+
+      if (triggerChangeEvent) {
+        $(this._element).toggleClass(ClassName.ACTIVE);
+      }
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      this._element = null;
+    }; // static
+
+
+    Button._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        if (!data) {
+          data = new Button(this);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (config === 'toggle') {
+          data[config]();
+        }
+      });
+    };
+
+    createClass(Button, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }]);
+    return Button;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+    event.preventDefault();
+    var button = event.target;
+
+    if (!$(button).hasClass(ClassName.BUTTON)) {
+      button = $(button).closest(Selector.BUTTON);
+    }
+
+    Button._jQueryInterface.call($(button), 'toggle');
+  }).on(Event.FOCUS_BLUR_DATA_API, Selector.DATA_TOGGLE_CARROT, function (event) {
+    var button = $(event.target).closest(Selector.BUTTON)[0];
+    $(button).toggleClass(ClassName.FOCUS, /^focus(in)?$/.test(event.type));
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Button._jQueryInterface;
+  $.fn[NAME].Constructor = Button;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Button._jQueryInterface;
+  };
+
+  return Button;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): carousel.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Carousel = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'carousel';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.carousel';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
+  var ARROW_LEFT_KEYCODE = 37; // KeyboardEvent.which value for left arrow key
+
+  var ARROW_RIGHT_KEYCODE = 39; // KeyboardEvent.which value for right arrow key
+
+  var TOUCHEVENT_COMPAT_WAIT = 500; // Time for mouse compat events to fire after touch
+
+  var Default = {
+    interval: 5000,
+    keyboard: true,
+    slide: false,
+    pause: 'hover',
+    wrap: true
+  };
+  var DefaultType = {
+    interval: '(number|boolean)',
+    keyboard: 'boolean',
+    slide: '(boolean|string)',
+    pause: '(string|boolean)',
+    wrap: 'boolean'
+  };
+  var Direction = {
+    NEXT: 'next',
+    PREV: 'prev',
+    LEFT: 'left',
+    RIGHT: 'right'
+  };
+  var Event = {
+    SLIDE: "slide" + EVENT_KEY,
+    SLID: "slid" + EVENT_KEY,
+    KEYDOWN: "keydown" + EVENT_KEY,
+    MOUSEENTER: "mouseenter" + EVENT_KEY,
+    MOUSELEAVE: "mouseleave" + EVENT_KEY,
+    TOUCHEND: "touchend" + EVENT_KEY,
+    LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    CAROUSEL: 'carousel',
+    ACTIVE: 'active',
+    SLIDE: 'slide',
+    RIGHT: 'carousel-item-right',
+    LEFT: 'carousel-item-left',
+    NEXT: 'carousel-item-next',
+    PREV: 'carousel-item-prev',
+    ITEM: 'carousel-item'
+  };
+  var Selector = {
+    ACTIVE: '.active',
+    ACTIVE_ITEM: '.active.carousel-item',
+    ITEM: '.carousel-item',
+    NEXT_PREV: '.carousel-item-next, .carousel-item-prev',
+    INDICATORS: '.carousel-indicators',
+    DATA_SLIDE: '[data-slide], [data-slide-to]',
+    DATA_RIDE: '[data-ride="carousel"]'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Carousel =
+  /*#__PURE__*/
+  function () {
+    function Carousel(element, config) {
+      this._items = null;
+      this._interval = null;
+      this._activeElement = null;
+      this._isPaused = false;
+      this._isSliding = false;
+      this.touchTimeout = null;
+      this._config = this._getConfig(config);
+      this._element = $(element)[0];
+      this._indicatorsElement = $(this._element).find(Selector.INDICATORS)[0];
+
+      this._addEventListeners();
+    } // getters
+
+
+    var _proto = Carousel.prototype;
+
+    // public
+    _proto.next = function next() {
+      if (!this._isSliding) {
+        this._slide(Direction.NEXT);
+      }
+    };
+
+    _proto.nextWhenVisible = function nextWhenVisible() {
+      // Don't call next when the page isn't visible
+      // or the carousel or its parent isn't visible
+      if (!document.hidden && $(this._element).is(':visible') && $(this._element).css('visibility') !== 
'hidden') {
+        this.next();
+      }
+    };
+
+    _proto.prev = function prev() {
+      if (!this._isSliding) {
+        this._slide(Direction.PREV);
+      }
+    };
+
+    _proto.pause = function pause(event) {
+      if (!event) {
+        this._isPaused = true;
+      }
+
+      if ($(this._element).find(Selector.NEXT_PREV)[0] && Util.supportsTransitionEnd()) {
+        Util.triggerTransitionEnd(this._element);
+        this.cycle(true);
+      }
+
+      clearInterval(this._interval);
+      this._interval = null;
+    };
+
+    _proto.cycle = function cycle(event) {
+      if (!event) {
+        this._isPaused = false;
+      }
+
+      if (this._interval) {
+        clearInterval(this._interval);
+        this._interval = null;
+      }
+
+      if (this._config.interval && !this._isPaused) {
+        this._interval = setInterval((document.visibilityState ? this.nextWhenVisible : 
this.next).bind(this), this._config.interval);
+      }
+    };
+
+    _proto.to = function to(index) {
+      var _this = this;
+
+      this._activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+
+      var activeIndex = this._getItemIndex(this._activeElement);
+
+      if (index > this._items.length - 1 || index < 0) {
+        return;
+      }
+
+      if (this._isSliding) {
+        $(this._element).one(Event.SLID, function () {
+          return _this.to(index);
+        });
+        return;
+      }
+
+      if (activeIndex === index) {
+        this.pause();
+        this.cycle();
+        return;
+      }
+
+      var direction = index > activeIndex ? Direction.NEXT : Direction.PREV;
+
+      this._slide(direction, this._items[index]);
+    };
+
+    _proto.dispose = function dispose() {
+      $(this._element).off(EVENT_KEY);
+      $.removeData(this._element, DATA_KEY);
+      this._items = null;
+      this._config = null;
+      this._element = null;
+      this._interval = null;
+      this._isPaused = null;
+      this._isSliding = null;
+      this._activeElement = null;
+      this._indicatorsElement = null;
+    }; // private
+
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, Default, config);
+      Util.typeCheckConfig(NAME, config, DefaultType);
+      return config;
+    };
+
+    _proto._addEventListeners = function _addEventListeners() {
+      var _this2 = this;
+
+      if (this._config.keyboard) {
+        $(this._element).on(Event.KEYDOWN, function (event) {
+          return _this2._keydown(event);
+        });
+      }
+
+      if (this._config.pause === 'hover') {
+        $(this._element).on(Event.MOUSEENTER, function (event) {
+          return _this2.pause(event);
+        }).on(Event.MOUSELEAVE, function (event) {
+          return _this2.cycle(event);
+        });
+
+        if ('ontouchstart' in document.documentElement) {
+          // if it's a touch-enabled device, mouseenter/leave are fired as
+          // part of the mouse compatibility events on first tap - the carousel
+          // would stop cycling until user tapped out of it;
+          // here, we listen for touchend, explicitly pause the carousel
+          // (as if it's the second time we tap on it, mouseenter compat event
+          // is NOT fired) and after a timeout (to allow for mouse compatibility
+          // events to fire) we explicitly restart cycling
+          $(this._element).on(Event.TOUCHEND, function () {
+            _this2.pause();
+
+            if (_this2.touchTimeout) {
+              clearTimeout(_this2.touchTimeout);
+            }
+
+            _this2.touchTimeout = setTimeout(function (event) {
+              return _this2.cycle(event);
+            }, TOUCHEVENT_COMPAT_WAIT + _this2._config.interval);
+          });
+        }
+      }
+    };
+
+    _proto._keydown = function _keydown(event) {
+      if (/input|textarea/i.test(event.target.tagName)) {
+        return;
+      }
+
+      switch (event.which) {
+        case ARROW_LEFT_KEYCODE:
+          event.preventDefault();
+          this.prev();
+          break;
+
+        case ARROW_RIGHT_KEYCODE:
+          event.preventDefault();
+          this.next();
+          break;
+
+        default:
+          return;
+      }
+    };
+
+    _proto._getItemIndex = function _getItemIndex(element) {
+      this._items = $.makeArray($(element).parent().find(Selector.ITEM));
+      return this._items.indexOf(element);
+    };
+
+    _proto._getItemByDirection = function _getItemByDirection(direction, activeElement) {
+      var isNextDirection = direction === Direction.NEXT;
+      var isPrevDirection = direction === Direction.PREV;
+
+      var activeIndex = this._getItemIndex(activeElement);
+
+      var lastItemIndex = this._items.length - 1;
+      var isGoingToWrap = isPrevDirection && activeIndex === 0 || isNextDirection && activeIndex === 
lastItemIndex;
+
+      if (isGoingToWrap && !this._config.wrap) {
+        return activeElement;
+      }
+
+      var delta = direction === Direction.PREV ? -1 : 1;
+      var itemIndex = (activeIndex + delta) % this._items.length;
+      return itemIndex === -1 ? this._items[this._items.length - 1] : this._items[itemIndex];
+    };
+
+    _proto._triggerSlideEvent = function _triggerSlideEvent(relatedTarget, eventDirectionName) {
+      var targetIndex = this._getItemIndex(relatedTarget);
+
+      var fromIndex = this._getItemIndex($(this._element).find(Selector.ACTIVE_ITEM)[0]);
+
+      var slideEvent = $.Event(Event.SLIDE, {
+        relatedTarget: relatedTarget,
+        direction: eventDirectionName,
+        from: fromIndex,
+        to: targetIndex
+      });
+      $(this._element).trigger(slideEvent);
+      return slideEvent;
+    };
+
+    _proto._setActiveIndicatorElement = function _setActiveIndicatorElement(element) {
+      if (this._indicatorsElement) {
+        $(this._indicatorsElement).find(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
+
+        var nextIndicator = this._indicatorsElement.children[this._getItemIndex(element)];
+
+        if (nextIndicator) {
+          $(nextIndicator).addClass(ClassName.ACTIVE);
+        }
+      }
+    };
+
+    _proto._slide = function _slide(direction, element) {
+      var _this3 = this;
+
+      var activeElement = $(this._element).find(Selector.ACTIVE_ITEM)[0];
+
+      var activeElementIndex = this._getItemIndex(activeElement);
+
+      var nextElement = element || activeElement && this._getItemByDirection(direction, activeElement);
+
+      var nextElementIndex = this._getItemIndex(nextElement);
+
+      var isCycling = Boolean(this._interval);
+      var directionalClassName;
+      var orderClassName;
+      var eventDirectionName;
+
+      if (direction === Direction.NEXT) {
+        directionalClassName = ClassName.LEFT;
+        orderClassName = ClassName.NEXT;
+        eventDirectionName = Direction.LEFT;
+      } else {
+        directionalClassName = ClassName.RIGHT;
+        orderClassName = ClassName.PREV;
+        eventDirectionName = Direction.RIGHT;
+      }
+
+      if (nextElement && $(nextElement).hasClass(ClassName.ACTIVE)) {
+        this._isSliding = false;
+        return;
+      }
+
+      var slideEvent = this._triggerSlideEvent(nextElement, eventDirectionName);
+
+      if (slideEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      if (!activeElement || !nextElement) {
+        // some weirdness is happening, so we bail
+        return;
+      }
+
+      this._isSliding = true;
+
+      if (isCycling) {
+        this.pause();
+      }
+
+      this._setActiveIndicatorElement(nextElement);
+
+      var slidEvent = $.Event(Event.SLID, {
+        relatedTarget: nextElement,
+        direction: eventDirectionName,
+        from: activeElementIndex,
+        to: nextElementIndex
+      });
+
+      if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.SLIDE)) {
+        $(nextElement).addClass(orderClassName);
+        Util.reflow(nextElement);
+        $(activeElement).addClass(directionalClassName);
+        $(nextElement).addClass(directionalClassName);
+        $(activeElement).one(Util.TRANSITION_END, function () {
+          $(nextElement).removeClass(directionalClassName + " " + orderClassName).addClass(ClassName.ACTIVE);
+          $(activeElement).removeClass(ClassName.ACTIVE + " " + orderClassName + " " + directionalClassName);
+          _this3._isSliding = false;
+          setTimeout(function () {
+            return $(_this3._element).trigger(slidEvent);
+          }, 0);
+        }).emulateTransitionEnd(TRANSITION_DURATION);
+      } else {
+        $(activeElement).removeClass(ClassName.ACTIVE);
+        $(nextElement).addClass(ClassName.ACTIVE);
+        this._isSliding = false;
+        $(this._element).trigger(slidEvent);
+      }
+
+      if (isCycling) {
+        this.cycle();
+      }
+    }; // static
+
+
+    Carousel._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = $.extend({}, Default, $(this).data());
+
+        if (typeof config === 'object') {
+          $.extend(_config, config);
+        }
+
+        var action = typeof config === 'string' ? config : _config.slide;
+
+        if (!data) {
+          data = new Carousel(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'number') {
+          data.to(config);
+        } else if (typeof action === 'string') {
+          if (typeof data[action] === 'undefined') {
+            throw new Error("No method named \"" + action + "\"");
+          }
+
+          data[action]();
+        } else if (_config.interval) {
+          data.pause();
+          data.cycle();
+        }
+      });
+    };
+
+    Carousel._dataApiClickHandler = function _dataApiClickHandler(event) {
+      var selector = Util.getSelectorFromElement(this);
+
+      if (!selector) {
+        return;
+      }
+
+      var target = $(selector)[0];
+
+      if (!target || !$(target).hasClass(ClassName.CAROUSEL)) {
+        return;
+      }
+
+      var config = $.extend({}, $(target).data(), $(this).data());
+      var slideIndex = this.getAttribute('data-slide-to');
+
+      if (slideIndex) {
+        config.interval = false;
+      }
+
+      Carousel._jQueryInterface.call($(target), config);
+
+      if (slideIndex) {
+        $(target).data(DATA_KEY).to(slideIndex);
+      }
+
+      event.preventDefault();
+    };
+
+    createClass(Carousel, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }]);
+    return Carousel;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_SLIDE, Carousel._dataApiClickHandler);
+  $(window).on(Event.LOAD_DATA_API, function () {
+    $(Selector.DATA_RIDE).each(function () {
+      var $carousel = $(this);
+
+      Carousel._jQueryInterface.call($carousel, $carousel.data());
+    });
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Carousel._jQueryInterface;
+  $.fn[NAME].Constructor = Carousel;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Carousel._jQueryInterface;
+  };
+
+  return Carousel;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): collapse.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Collapse = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'collapse';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.collapse';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 600;
+  var Default = {
+    toggle: true,
+    parent: ''
+  };
+  var DefaultType = {
+    toggle: 'boolean',
+    parent: '(string|element)'
+  };
+  var Event = {
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    SHOW: 'show',
+    COLLAPSE: 'collapse',
+    COLLAPSING: 'collapsing',
+    COLLAPSED: 'collapsed'
+  };
+  var Dimension = {
+    WIDTH: 'width',
+    HEIGHT: 'height'
+  };
+  var Selector = {
+    ACTIVES: '.show, .collapsing',
+    DATA_TOGGLE: '[data-toggle="collapse"]'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Collapse =
+  /*#__PURE__*/
+  function () {
+    function Collapse(element, config) {
+      this._isTransitioning = false;
+      this._element = element;
+      this._config = this._getConfig(config);
+      this._triggerArray = $.makeArray($("[data-toggle=\"collapse\"][href=\"#" + element.id + "\"]," + 
("[data-toggle=\"collapse\"][data-target=\"#" + element.id + "\"]")));
+      var tabToggles = $(Selector.DATA_TOGGLE);
+
+      for (var i = 0; i < tabToggles.length; i++) {
+        var elem = tabToggles[i];
+        var selector = Util.getSelectorFromElement(elem);
+
+        if (selector !== null && $(selector).filter(element).length > 0) {
+          this._triggerArray.push(elem);
+        }
+      }
+
+      this._parent = this._config.parent ? this._getParent() : null;
+
+      if (!this._config.parent) {
+        this._addAriaAndCollapsedClass(this._element, this._triggerArray);
+      }
+
+      if (this._config.toggle) {
+        this.toggle();
+      }
+    } // getters
+
+
+    var _proto = Collapse.prototype;
+
+    // public
+    _proto.toggle = function toggle() {
+      if ($(this._element).hasClass(ClassName.SHOW)) {
+        this.hide();
+      } else {
+        this.show();
+      }
+    };
+
+    _proto.show = function show() {
+      var _this = this;
+
+      if (this._isTransitioning || $(this._element).hasClass(ClassName.SHOW)) {
+        return;
+      }
+
+      var actives;
+      var activesData;
+
+      if (this._parent) {
+        actives = $.makeArray($(this._parent).children().children(Selector.ACTIVES));
+
+        if (!actives.length) {
+          actives = null;
+        }
+      }
+
+      if (actives) {
+        activesData = $(actives).data(DATA_KEY);
+
+        if (activesData && activesData._isTransitioning) {
+          return;
+        }
+      }
+
+      var startEvent = $.Event(Event.SHOW);
+      $(this._element).trigger(startEvent);
+
+      if (startEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      if (actives) {
+        Collapse._jQueryInterface.call($(actives), 'hide');
+
+        if (!activesData) {
+          $(actives).data(DATA_KEY, null);
+        }
+      }
+
+      var dimension = this._getDimension();
+
+      $(this._element).removeClass(ClassName.COLLAPSE).addClass(ClassName.COLLAPSING);
+      this._element.style[dimension] = 0;
+
+      if (this._triggerArray.length) {
+        $(this._triggerArray).removeClass(ClassName.COLLAPSED).attr('aria-expanded', true);
+      }
+
+      this.setTransitioning(true);
+
+      var complete = function complete() {
+        
$(_this._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).addClass(ClassName.SHOW);
+        _this._element.style[dimension] = '';
+
+        _this.setTransitioning(false);
+
+        $(_this._element).trigger(Event.SHOWN);
+      };
+
+      if (!Util.supportsTransitionEnd()) {
+        complete();
+        return;
+      }
+
+      var capitalizedDimension = dimension[0].toUpperCase() + dimension.slice(1);
+      var scrollSize = "scroll" + capitalizedDimension;
+      $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+      this._element.style[dimension] = this._element[scrollSize] + "px";
+    };
+
+    _proto.hide = function hide() {
+      var _this2 = this;
+
+      if (this._isTransitioning || !$(this._element).hasClass(ClassName.SHOW)) {
+        return;
+      }
+
+      var startEvent = $.Event(Event.HIDE);
+      $(this._element).trigger(startEvent);
+
+      if (startEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      var dimension = this._getDimension();
+
+      this._element.style[dimension] = this._element.getBoundingClientRect()[dimension] + "px";
+      Util.reflow(this._element);
+      
$(this._element).addClass(ClassName.COLLAPSING).removeClass(ClassName.COLLAPSE).removeClass(ClassName.SHOW);
+
+      if (this._triggerArray.length) {
+        for (var i = 0; i < this._triggerArray.length; i++) {
+          var trigger = this._triggerArray[i];
+          var selector = Util.getSelectorFromElement(trigger);
+
+          if (selector !== null) {
+            var $elem = $(selector);
+
+            if (!$elem.hasClass(ClassName.SHOW)) {
+              $(trigger).addClass(ClassName.COLLAPSED).attr('aria-expanded', false);
+            }
+          }
+        }
+      }
+
+      this.setTransitioning(true);
+
+      var complete = function complete() {
+        _this2.setTransitioning(false);
+
+        
$(_this2._element).removeClass(ClassName.COLLAPSING).addClass(ClassName.COLLAPSE).trigger(Event.HIDDEN);
+      };
+
+      this._element.style[dimension] = '';
+
+      if (!Util.supportsTransitionEnd()) {
+        complete();
+        return;
+      }
+
+      $(this._element).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+    };
+
+    _proto.setTransitioning = function setTransitioning(isTransitioning) {
+      this._isTransitioning = isTransitioning;
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      this._config = null;
+      this._parent = null;
+      this._element = null;
+      this._triggerArray = null;
+      this._isTransitioning = null;
+    }; // private
+
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, Default, config);
+      config.toggle = Boolean(config.toggle); // coerce string values
+
+      Util.typeCheckConfig(NAME, config, DefaultType);
+      return config;
+    };
+
+    _proto._getDimension = function _getDimension() {
+      var hasWidth = $(this._element).hasClass(Dimension.WIDTH);
+      return hasWidth ? Dimension.WIDTH : Dimension.HEIGHT;
+    };
+
+    _proto._getParent = function _getParent() {
+      var _this3 = this;
+
+      var parent = null;
+
+      if (Util.isElement(this._config.parent)) {
+        parent = this._config.parent; // it's a jQuery object
+
+        if (typeof this._config.parent.jquery !== 'undefined') {
+          parent = this._config.parent[0];
+        }
+      } else {
+        parent = $(this._config.parent)[0];
+      }
+
+      var selector = "[data-toggle=\"collapse\"][data-parent=\"" + this._config.parent + "\"]";
+      $(parent).find(selector).each(function (i, element) {
+        _this3._addAriaAndCollapsedClass(Collapse._getTargetFromElement(element), [element]);
+      });
+      return parent;
+    };
+
+    _proto._addAriaAndCollapsedClass = function _addAriaAndCollapsedClass(element, triggerArray) {
+      if (element) {
+        var isOpen = $(element).hasClass(ClassName.SHOW);
+
+        if (triggerArray.length) {
+          $(triggerArray).toggleClass(ClassName.COLLAPSED, !isOpen).attr('aria-expanded', isOpen);
+        }
+      }
+    }; // static
+
+
+    Collapse._getTargetFromElement = function _getTargetFromElement(element) {
+      var selector = Util.getSelectorFromElement(element);
+      return selector ? $(selector)[0] : null;
+    };
+
+    Collapse._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var $this = $(this);
+        var data = $this.data(DATA_KEY);
+
+        var _config = $.extend({}, Default, $this.data(), typeof config === 'object' && config);
+
+        if (!data && _config.toggle && /show|hide/.test(config)) {
+          _config.toggle = false;
+        }
+
+        if (!data) {
+          data = new Collapse(this, _config);
+          $this.data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    createClass(Collapse, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }]);
+    return Collapse;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    // preventDefault only for <a> elements (which change the URL) not inside the collapsible element
+    if (event.currentTarget.tagName === 'A') {
+      event.preventDefault();
+    }
+
+    var $trigger = $(this);
+    var selector = Util.getSelectorFromElement(this);
+    $(selector).each(function () {
+      var $target = $(this);
+      var data = $target.data(DATA_KEY);
+      var config = data ? 'toggle' : $trigger.data();
+
+      Collapse._jQueryInterface.call($target, config);
+    });
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Collapse._jQueryInterface;
+  $.fn[NAME].Constructor = Collapse;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Collapse._jQueryInterface;
+  };
+
+  return Collapse;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): dropdown.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Dropdown = function () {
+  /**
+   * Check for Popper dependency
+   * Popper - https://popper.js.org
+   */
+  if (typeof Popper === 'undefined') {
+    throw new Error('Bootstrap dropdown require Popper.js (https://popper.js.org)');
+  }
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+
+  var NAME = 'dropdown';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.dropdown';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
+
+  var SPACE_KEYCODE = 32; // KeyboardEvent.which value for space key
+
+  var TAB_KEYCODE = 9; // KeyboardEvent.which value for tab key
+
+  var ARROW_UP_KEYCODE = 38; // KeyboardEvent.which value for up arrow key
+
+  var ARROW_DOWN_KEYCODE = 40; // KeyboardEvent.which value for down arrow key
+
+  var RIGHT_MOUSE_BUTTON_WHICH = 3; // MouseEvent.which value for the right button (assuming a right-handed 
mouse)
+
+  var REGEXP_KEYDOWN = new RegExp(ARROW_UP_KEYCODE + "|" + ARROW_DOWN_KEYCODE + "|" + ESCAPE_KEYCODE);
+  var Event = {
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    CLICK: "click" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY,
+    KEYDOWN_DATA_API: "keydown" + EVENT_KEY + DATA_API_KEY,
+    KEYUP_DATA_API: "keyup" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    DISABLED: 'disabled',
+    SHOW: 'show',
+    DROPUP: 'dropup',
+    MENURIGHT: 'dropdown-menu-right',
+    MENULEFT: 'dropdown-menu-left'
+  };
+  var Selector = {
+    DATA_TOGGLE: '[data-toggle="dropdown"]',
+    FORM_CHILD: '.dropdown form',
+    MENU: '.dropdown-menu',
+    NAVBAR_NAV: '.navbar-nav',
+    VISIBLE_ITEMS: '.dropdown-menu .dropdown-item:not(.disabled)'
+  };
+  var AttachmentMap = {
+    TOP: 'top-start',
+    TOPEND: 'top-end',
+    BOTTOM: 'bottom-start',
+    BOTTOMEND: 'bottom-end'
+  };
+  var Default = {
+    offset: 0,
+    flip: true
+  };
+  var DefaultType = {
+    offset: '(number|string|function)',
+    flip: 'boolean'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Dropdown =
+  /*#__PURE__*/
+  function () {
+    function Dropdown(element, config) {
+      this._element = element;
+      this._popper = null;
+      this._config = this._getConfig(config);
+      this._menu = this._getMenuElement();
+      this._inNavbar = this._detectNavbar();
+
+      this._addEventListeners();
+    } // getters
+
+
+    var _proto = Dropdown.prototype;
+
+    // public
+    _proto.toggle = function toggle() {
+      if (this._element.disabled || $(this._element).hasClass(ClassName.DISABLED)) {
+        return;
+      }
+
+      var parent = Dropdown._getParentFromElement(this._element);
+
+      var isActive = $(this._menu).hasClass(ClassName.SHOW);
+
+      Dropdown._clearMenus();
+
+      if (isActive) {
+        return;
+      }
+
+      var relatedTarget = {
+        relatedTarget: this._element
+      };
+      var showEvent = $.Event(Event.SHOW, relatedTarget);
+      $(parent).trigger(showEvent);
+
+      if (showEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      var element = this._element; // for dropup with alignment we use the parent as popper container
+
+      if ($(parent).hasClass(ClassName.DROPUP)) {
+        if ($(this._menu).hasClass(ClassName.MENULEFT) || $(this._menu).hasClass(ClassName.MENURIGHT)) {
+          element = parent;
+        }
+      }
+
+      this._popper = new Popper(element, this._menu, this._getPopperConfig()); // if this is a touch-enabled 
device we add extra
+      // empty mouseover listeners to the body's immediate children;
+      // only needed because of broken event delegation on iOS
+      // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+
+      if ('ontouchstart' in document.documentElement && !$(parent).closest(Selector.NAVBAR_NAV).length) {
+        $('body').children().on('mouseover', null, $.noop);
+      }
+
+      this._element.focus();
+
+      this._element.setAttribute('aria-expanded', true);
+
+      $(this._menu).toggleClass(ClassName.SHOW);
+      $(parent).toggleClass(ClassName.SHOW).trigger($.Event(Event.SHOWN, relatedTarget));
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      $(this._element).off(EVENT_KEY);
+      this._element = null;
+      this._menu = null;
+
+      if (this._popper !== null) {
+        this._popper.destroy();
+      }
+
+      this._popper = null;
+    };
+
+    _proto.update = function update() {
+      this._inNavbar = this._detectNavbar();
+
+      if (this._popper !== null) {
+        this._popper.scheduleUpdate();
+      }
+    }; // private
+
+
+    _proto._addEventListeners = function _addEventListeners() {
+      var _this = this;
+
+      $(this._element).on(Event.CLICK, function (event) {
+        event.preventDefault();
+        event.stopPropagation();
+
+        _this.toggle();
+      });
+    };
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, this.constructor.Default, $(this._element).data(), config);
+      Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
+      return config;
+    };
+
+    _proto._getMenuElement = function _getMenuElement() {
+      if (!this._menu) {
+        var parent = Dropdown._getParentFromElement(this._element);
+
+        this._menu = $(parent).find(Selector.MENU)[0];
+      }
+
+      return this._menu;
+    };
+
+    _proto._getPlacement = function _getPlacement() {
+      var $parentDropdown = $(this._element).parent();
+      var placement = AttachmentMap.BOTTOM; // Handle dropup
+
+      if ($parentDropdown.hasClass(ClassName.DROPUP)) {
+        placement = AttachmentMap.TOP;
+
+        if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
+          placement = AttachmentMap.TOPEND;
+        }
+      } else if ($(this._menu).hasClass(ClassName.MENURIGHT)) {
+        placement = AttachmentMap.BOTTOMEND;
+      }
+
+      return placement;
+    };
+
+    _proto._detectNavbar = function _detectNavbar() {
+      return $(this._element).closest('.navbar').length > 0;
+    };
+
+    _proto._getPopperConfig = function _getPopperConfig() {
+      var _this2 = this;
+
+      var offsetConf = {};
+
+      if (typeof this._config.offset === 'function') {
+        offsetConf.fn = function (data) {
+          data.offsets = $.extend({}, data.offsets, _this2._config.offset(data.offsets) || {});
+          return data;
+        };
+      } else {
+        offsetConf.offset = this._config.offset;
+      }
+
+      var popperConfig = {
+        placement: this._getPlacement(),
+        modifiers: {
+          offset: offsetConf,
+          flip: {
+            enabled: this._config.flip
+          }
+        } // Disable Popper.js for Dropdown in Navbar
+
+      };
+
+      if (this._inNavbar) {
+        popperConfig.modifiers.applyStyle = {
+          enabled: !this._inNavbar
+        };
+      }
+
+      return popperConfig;
+    }; // static
+
+
+    Dropdown._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = typeof config === 'object' ? config : null;
+
+        if (!data) {
+          data = new Dropdown(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    Dropdown._clearMenus = function _clearMenus(event) {
+      if (event && (event.which === RIGHT_MOUSE_BUTTON_WHICH || event.type === 'keyup' && event.which !== 
TAB_KEYCODE)) {
+        return;
+      }
+
+      var toggles = $.makeArray($(Selector.DATA_TOGGLE));
+
+      for (var i = 0; i < toggles.length; i++) {
+        var parent = Dropdown._getParentFromElement(toggles[i]);
+
+        var context = $(toggles[i]).data(DATA_KEY);
+        var relatedTarget = {
+          relatedTarget: toggles[i]
+        };
+
+        if (!context) {
+          continue;
+        }
+
+        var dropdownMenu = context._menu;
+
+        if (!$(parent).hasClass(ClassName.SHOW)) {
+          continue;
+        }
+
+        if (event && (event.type === 'click' && /input|textarea/i.test(event.target.tagName) || event.type 
=== 'keyup' && event.which === TAB_KEYCODE) && $.contains(parent, event.target)) {
+          continue;
+        }
+
+        var hideEvent = $.Event(Event.HIDE, relatedTarget);
+        $(parent).trigger(hideEvent);
+
+        if (hideEvent.isDefaultPrevented()) {
+          continue;
+        } // if this is a touch-enabled device we remove the extra
+        // empty mouseover listeners we added for iOS support
+
+
+        if ('ontouchstart' in document.documentElement) {
+          $('body').children().off('mouseover', null, $.noop);
+        }
+
+        toggles[i].setAttribute('aria-expanded', 'false');
+        $(dropdownMenu).removeClass(ClassName.SHOW);
+        $(parent).removeClass(ClassName.SHOW).trigger($.Event(Event.HIDDEN, relatedTarget));
+      }
+    };
+
+    Dropdown._getParentFromElement = function _getParentFromElement(element) {
+      var parent;
+      var selector = Util.getSelectorFromElement(element);
+
+      if (selector) {
+        parent = $(selector)[0];
+      }
+
+      return parent || element.parentNode;
+    };
+
+    Dropdown._dataApiKeydownHandler = function _dataApiKeydownHandler(event) {
+      if (!REGEXP_KEYDOWN.test(event.which) || /button/i.test(event.target.tagName) && event.which === 
SPACE_KEYCODE || /input|textarea/i.test(event.target.tagName)) {
+        return;
+      }
+
+      event.preventDefault();
+      event.stopPropagation();
+
+      if (this.disabled || $(this).hasClass(ClassName.DISABLED)) {
+        return;
+      }
+
+      var parent = Dropdown._getParentFromElement(this);
+
+      var isActive = $(parent).hasClass(ClassName.SHOW);
+
+      if (!isActive && (event.which !== ESCAPE_KEYCODE || event.which !== SPACE_KEYCODE) || isActive && 
(event.which === ESCAPE_KEYCODE || event.which === SPACE_KEYCODE)) {
+        if (event.which === ESCAPE_KEYCODE) {
+          var toggle = $(parent).find(Selector.DATA_TOGGLE)[0];
+          $(toggle).trigger('focus');
+        }
+
+        $(this).trigger('click');
+        return;
+      }
+
+      var items = $(parent).find(Selector.VISIBLE_ITEMS).get();
+
+      if (!items.length) {
+        return;
+      }
+
+      var index = items.indexOf(event.target);
+
+      if (event.which === ARROW_UP_KEYCODE && index > 0) {
+        // up
+        index--;
+      }
+
+      if (event.which === ARROW_DOWN_KEYCODE && index < items.length - 1) {
+        // down
+        index++;
+      }
+
+      if (index < 0) {
+        index = 0;
+      }
+
+      items[index].focus();
+    };
+
+    createClass(Dropdown, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }, {
+      key: "DefaultType",
+      get: function get() {
+        return DefaultType;
+      }
+    }]);
+    return Dropdown;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.KEYDOWN_DATA_API, Selector.DATA_TOGGLE, 
Dropdown._dataApiKeydownHandler).on(Event.KEYDOWN_DATA_API, Selector.MENU, 
Dropdown._dataApiKeydownHandler).on(Event.CLICK_DATA_API + " " + Event.KEYUP_DATA_API, 
Dropdown._clearMenus).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    event.preventDefault();
+    event.stopPropagation();
+
+    Dropdown._jQueryInterface.call($(this), 'toggle');
+  }).on(Event.CLICK_DATA_API, Selector.FORM_CHILD, function (e) {
+    e.stopPropagation();
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Dropdown._jQueryInterface;
+  $.fn[NAME].Constructor = Dropdown;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Dropdown._jQueryInterface;
+  };
+
+  return Dropdown;
+}($, Popper);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): modal.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Modal = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'modal';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.modal';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 300;
+  var BACKDROP_TRANSITION_DURATION = 150;
+  var ESCAPE_KEYCODE = 27; // KeyboardEvent.which value for Escape (Esc) key
+
+  var Default = {
+    backdrop: true,
+    keyboard: true,
+    focus: true,
+    show: true
+  };
+  var DefaultType = {
+    backdrop: '(boolean|string)',
+    keyboard: 'boolean',
+    focus: 'boolean',
+    show: 'boolean'
+  };
+  var Event = {
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    FOCUSIN: "focusin" + EVENT_KEY,
+    RESIZE: "resize" + EVENT_KEY,
+    CLICK_DISMISS: "click.dismiss" + EVENT_KEY,
+    KEYDOWN_DISMISS: "keydown.dismiss" + EVENT_KEY,
+    MOUSEUP_DISMISS: "mouseup.dismiss" + EVENT_KEY,
+    MOUSEDOWN_DISMISS: "mousedown.dismiss" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    SCROLLBAR_MEASURER: 'modal-scrollbar-measure',
+    BACKDROP: 'modal-backdrop',
+    OPEN: 'modal-open',
+    FADE: 'fade',
+    SHOW: 'show'
+  };
+  var Selector = {
+    DIALOG: '.modal-dialog',
+    DATA_TOGGLE: '[data-toggle="modal"]',
+    DATA_DISMISS: '[data-dismiss="modal"]',
+    FIXED_CONTENT: '.fixed-top, .fixed-bottom, .is-fixed, .sticky-top',
+    STICKY_CONTENT: '.sticky-top',
+    NAVBAR_TOGGLER: '.navbar-toggler'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Modal =
+  /*#__PURE__*/
+  function () {
+    function Modal(element, config) {
+      this._config = this._getConfig(config);
+      this._element = element;
+      this._dialog = $(element).find(Selector.DIALOG)[0];
+      this._backdrop = null;
+      this._isShown = false;
+      this._isBodyOverflowing = false;
+      this._ignoreBackdropClick = false;
+      this._originalBodyPadding = 0;
+      this._scrollbarWidth = 0;
+    } // getters
+
+
+    var _proto = Modal.prototype;
+
+    // public
+    _proto.toggle = function toggle(relatedTarget) {
+      return this._isShown ? this.hide() : this.show(relatedTarget);
+    };
+
+    _proto.show = function show(relatedTarget) {
+      var _this = this;
+
+      if (this._isTransitioning || this._isShown) {
+        return;
+      }
+
+      if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
+        this._isTransitioning = true;
+      }
+
+      var showEvent = $.Event(Event.SHOW, {
+        relatedTarget: relatedTarget
+      });
+      $(this._element).trigger(showEvent);
+
+      if (this._isShown || showEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      this._isShown = true;
+
+      this._checkScrollbar();
+
+      this._setScrollbar();
+
+      this._adjustDialog();
+
+      $(document.body).addClass(ClassName.OPEN);
+
+      this._setEscapeEvent();
+
+      this._setResizeEvent();
+
+      $(this._element).on(Event.CLICK_DISMISS, Selector.DATA_DISMISS, function (event) {
+        return _this.hide(event);
+      });
+      $(this._dialog).on(Event.MOUSEDOWN_DISMISS, function () {
+        $(_this._element).one(Event.MOUSEUP_DISMISS, function (event) {
+          if ($(event.target).is(_this._element)) {
+            _this._ignoreBackdropClick = true;
+          }
+        });
+      });
+
+      this._showBackdrop(function () {
+        return _this._showElement(relatedTarget);
+      });
+    };
+
+    _proto.hide = function hide(event) {
+      var _this2 = this;
+
+      if (event) {
+        event.preventDefault();
+      }
+
+      if (this._isTransitioning || !this._isShown) {
+        return;
+      }
+
+      var hideEvent = $.Event(Event.HIDE);
+      $(this._element).trigger(hideEvent);
+
+      if (!this._isShown || hideEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      this._isShown = false;
+      var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
+
+      if (transition) {
+        this._isTransitioning = true;
+      }
+
+      this._setEscapeEvent();
+
+      this._setResizeEvent();
+
+      $(document).off(Event.FOCUSIN);
+      $(this._element).removeClass(ClassName.SHOW);
+      $(this._element).off(Event.CLICK_DISMISS);
+      $(this._dialog).off(Event.MOUSEDOWN_DISMISS);
+
+      if (transition) {
+        $(this._element).one(Util.TRANSITION_END, function (event) {
+          return _this2._hideModal(event);
+        }).emulateTransitionEnd(TRANSITION_DURATION);
+      } else {
+        this._hideModal();
+      }
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      $(window, document, this._element, this._backdrop).off(EVENT_KEY);
+      this._config = null;
+      this._element = null;
+      this._dialog = null;
+      this._backdrop = null;
+      this._isShown = null;
+      this._isBodyOverflowing = null;
+      this._ignoreBackdropClick = null;
+      this._scrollbarWidth = null;
+    };
+
+    _proto.handleUpdate = function handleUpdate() {
+      this._adjustDialog();
+    }; // private
+
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, Default, config);
+      Util.typeCheckConfig(NAME, config, DefaultType);
+      return config;
+    };
+
+    _proto._showElement = function _showElement(relatedTarget) {
+      var _this3 = this;
+
+      var transition = Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE);
+
+      if (!this._element.parentNode || this._element.parentNode.nodeType !== Node.ELEMENT_NODE) {
+        // don't move modals dom position
+        document.body.appendChild(this._element);
+      }
+
+      this._element.style.display = 'block';
+
+      this._element.removeAttribute('aria-hidden');
+
+      this._element.scrollTop = 0;
+
+      if (transition) {
+        Util.reflow(this._element);
+      }
+
+      $(this._element).addClass(ClassName.SHOW);
+
+      if (this._config.focus) {
+        this._enforceFocus();
+      }
+
+      var shownEvent = $.Event(Event.SHOWN, {
+        relatedTarget: relatedTarget
+      });
+
+      var transitionComplete = function transitionComplete() {
+        if (_this3._config.focus) {
+          _this3._element.focus();
+        }
+
+        _this3._isTransitioning = false;
+        $(_this3._element).trigger(shownEvent);
+      };
+
+      if (transition) {
+        $(this._dialog).one(Util.TRANSITION_END, 
transitionComplete).emulateTransitionEnd(TRANSITION_DURATION);
+      } else {
+        transitionComplete();
+      }
+    };
+
+    _proto._enforceFocus = function _enforceFocus() {
+      var _this4 = this;
+
+      $(document).off(Event.FOCUSIN) // guard against infinite focus loop
+      .on(Event.FOCUSIN, function (event) {
+        if (document !== event.target && _this4._element !== event.target && 
!$(_this4._element).has(event.target).length) {
+          _this4._element.focus();
+        }
+      });
+    };
+
+    _proto._setEscapeEvent = function _setEscapeEvent() {
+      var _this5 = this;
+
+      if (this._isShown && this._config.keyboard) {
+        $(this._element).on(Event.KEYDOWN_DISMISS, function (event) {
+          if (event.which === ESCAPE_KEYCODE) {
+            event.preventDefault();
+
+            _this5.hide();
+          }
+        });
+      } else if (!this._isShown) {
+        $(this._element).off(Event.KEYDOWN_DISMISS);
+      }
+    };
+
+    _proto._setResizeEvent = function _setResizeEvent() {
+      var _this6 = this;
+
+      if (this._isShown) {
+        $(window).on(Event.RESIZE, function (event) {
+          return _this6.handleUpdate(event);
+        });
+      } else {
+        $(window).off(Event.RESIZE);
+      }
+    };
+
+    _proto._hideModal = function _hideModal() {
+      var _this7 = this;
+
+      this._element.style.display = 'none';
+
+      this._element.setAttribute('aria-hidden', true);
+
+      this._isTransitioning = false;
+
+      this._showBackdrop(function () {
+        $(document.body).removeClass(ClassName.OPEN);
+
+        _this7._resetAdjustments();
+
+        _this7._resetScrollbar();
+
+        $(_this7._element).trigger(Event.HIDDEN);
+      });
+    };
+
+    _proto._removeBackdrop = function _removeBackdrop() {
+      if (this._backdrop) {
+        $(this._backdrop).remove();
+        this._backdrop = null;
+      }
+    };
+
+    _proto._showBackdrop = function _showBackdrop(callback) {
+      var _this8 = this;
+
+      var animate = $(this._element).hasClass(ClassName.FADE) ? ClassName.FADE : '';
+
+      if (this._isShown && this._config.backdrop) {
+        var doAnimate = Util.supportsTransitionEnd() && animate;
+        this._backdrop = document.createElement('div');
+        this._backdrop.className = ClassName.BACKDROP;
+
+        if (animate) {
+          $(this._backdrop).addClass(animate);
+        }
+
+        $(this._backdrop).appendTo(document.body);
+        $(this._element).on(Event.CLICK_DISMISS, function (event) {
+          if (_this8._ignoreBackdropClick) {
+            _this8._ignoreBackdropClick = false;
+            return;
+          }
+
+          if (event.target !== event.currentTarget) {
+            return;
+          }
+
+          if (_this8._config.backdrop === 'static') {
+            _this8._element.focus();
+          } else {
+            _this8.hide();
+          }
+        });
+
+        if (doAnimate) {
+          Util.reflow(this._backdrop);
+        }
+
+        $(this._backdrop).addClass(ClassName.SHOW);
+
+        if (!callback) {
+          return;
+        }
+
+        if (!doAnimate) {
+          callback();
+          return;
+        }
+
+        $(this._backdrop).one(Util.TRANSITION_END, 
callback).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
+      } else if (!this._isShown && this._backdrop) {
+        $(this._backdrop).removeClass(ClassName.SHOW);
+
+        var callbackRemove = function callbackRemove() {
+          _this8._removeBackdrop();
+
+          if (callback) {
+            callback();
+          }
+        };
+
+        if (Util.supportsTransitionEnd() && $(this._element).hasClass(ClassName.FADE)) {
+          $(this._backdrop).one(Util.TRANSITION_END, 
callbackRemove).emulateTransitionEnd(BACKDROP_TRANSITION_DURATION);
+        } else {
+          callbackRemove();
+        }
+      } else if (callback) {
+        callback();
+      }
+    }; // ----------------------------------------------------------------------
+    // the following methods are used to handle overflowing modals
+    // todo (fat): these should probably be refactored out of modal.js
+    // ----------------------------------------------------------------------
+
+
+    _proto._adjustDialog = function _adjustDialog() {
+      var isModalOverflowing = this._element.scrollHeight > document.documentElement.clientHeight;
+
+      if (!this._isBodyOverflowing && isModalOverflowing) {
+        this._element.style.paddingLeft = this._scrollbarWidth + "px";
+      }
+
+      if (this._isBodyOverflowing && !isModalOverflowing) {
+        this._element.style.paddingRight = this._scrollbarWidth + "px";
+      }
+    };
+
+    _proto._resetAdjustments = function _resetAdjustments() {
+      this._element.style.paddingLeft = '';
+      this._element.style.paddingRight = '';
+    };
+
+    _proto._checkScrollbar = function _checkScrollbar() {
+      var rect = document.body.getBoundingClientRect();
+      this._isBodyOverflowing = rect.left + rect.right < window.innerWidth;
+      this._scrollbarWidth = this._getScrollbarWidth();
+    };
+
+    _proto._setScrollbar = function _setScrollbar() {
+      var _this9 = this;
+
+      if (this._isBodyOverflowing) {
+        // Note: DOMNode.style.paddingRight returns the actual value or '' if not set
+        //   while $(DOMNode).css('padding-right') returns the calculated value or 0 if not set
+        // Adjust fixed content padding
+        $(Selector.FIXED_CONTENT).each(function (index, element) {
+          var actualPadding = $(element)[0].style.paddingRight;
+          var calculatedPadding = $(element).css('padding-right');
+          $(element).data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) 
+ _this9._scrollbarWidth + "px");
+        }); // Adjust sticky content margin
+
+        $(Selector.STICKY_CONTENT).each(function (index, element) {
+          var actualMargin = $(element)[0].style.marginRight;
+          var calculatedMargin = $(element).css('margin-right');
+          $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) - 
_this9._scrollbarWidth + "px");
+        }); // Adjust navbar-toggler margin
+
+        $(Selector.NAVBAR_TOGGLER).each(function (index, element) {
+          var actualMargin = $(element)[0].style.marginRight;
+          var calculatedMargin = $(element).css('margin-right');
+          $(element).data('margin-right', actualMargin).css('margin-right', parseFloat(calculatedMargin) + 
_this9._scrollbarWidth + "px");
+        }); // Adjust body padding
+
+        var actualPadding = document.body.style.paddingRight;
+        var calculatedPadding = $('body').css('padding-right');
+        $('body').data('padding-right', actualPadding).css('padding-right', parseFloat(calculatedPadding) + 
this._scrollbarWidth + "px");
+      }
+    };
+
+    _proto._resetScrollbar = function _resetScrollbar() {
+      // Restore fixed content padding
+      $(Selector.FIXED_CONTENT).each(function (index, element) {
+        var padding = $(element).data('padding-right');
+
+        if (typeof padding !== 'undefined') {
+          $(element).css('padding-right', padding).removeData('padding-right');
+        }
+      }); // Restore sticky content and navbar-toggler margin
+
+      $(Selector.STICKY_CONTENT + ", " + Selector.NAVBAR_TOGGLER).each(function (index, element) {
+        var margin = $(element).data('margin-right');
+
+        if (typeof margin !== 'undefined') {
+          $(element).css('margin-right', margin).removeData('margin-right');
+        }
+      }); // Restore body padding
+
+      var padding = $('body').data('padding-right');
+
+      if (typeof padding !== 'undefined') {
+        $('body').css('padding-right', padding).removeData('padding-right');
+      }
+    };
+
+    _proto._getScrollbarWidth = function _getScrollbarWidth() {
+      // thx d.walsh
+      var scrollDiv = document.createElement('div');
+      scrollDiv.className = ClassName.SCROLLBAR_MEASURER;
+      document.body.appendChild(scrollDiv);
+      var scrollbarWidth = scrollDiv.getBoundingClientRect().width - scrollDiv.clientWidth;
+      document.body.removeChild(scrollDiv);
+      return scrollbarWidth;
+    }; // static
+
+
+    Modal._jQueryInterface = function _jQueryInterface(config, relatedTarget) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = $.extend({}, Modal.Default, $(this).data(), typeof config === 'object' && config);
+
+        if (!data) {
+          data = new Modal(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config](relatedTarget);
+        } else if (_config.show) {
+          data.show(relatedTarget);
+        }
+      });
+    };
+
+    createClass(Modal, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }]);
+    return Modal;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    var _this10 = this;
+
+    var target;
+    var selector = Util.getSelectorFromElement(this);
+
+    if (selector) {
+      target = $(selector)[0];
+    }
+
+    var config = $(target).data(DATA_KEY) ? 'toggle' : $.extend({}, $(target).data(), $(this).data());
+
+    if (this.tagName === 'A' || this.tagName === 'AREA') {
+      event.preventDefault();
+    }
+
+    var $target = $(target).one(Event.SHOW, function (showEvent) {
+      if (showEvent.isDefaultPrevented()) {
+        // only register focus restorer if modal will actually get shown
+        return;
+      }
+
+      $target.one(Event.HIDDEN, function () {
+        if ($(_this10).is(':visible')) {
+          _this10.focus();
+        }
+      });
+    });
+
+    Modal._jQueryInterface.call($(target), config, this);
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Modal._jQueryInterface;
+  $.fn[NAME].Constructor = Modal;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Modal._jQueryInterface;
+  };
+
+  return Modal;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): tooltip.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Tooltip = function () {
+  /**
+   * Check for Popper dependency
+   * Popper - https://popper.js.org
+   */
+  if (typeof Popper === 'undefined') {
+    throw new Error('Bootstrap tooltips require Popper.js (https://popper.js.org)');
+  }
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+
+
+  var NAME = 'tooltip';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.tooltip';
+  var EVENT_KEY = "." + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+  var CLASS_PREFIX = 'bs-tooltip';
+  var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
+  var DefaultType = {
+    animation: 'boolean',
+    template: 'string',
+    title: '(string|element|function)',
+    trigger: 'string',
+    delay: '(number|object)',
+    html: 'boolean',
+    selector: '(string|boolean)',
+    placement: '(string|function)',
+    offset: '(number|string)',
+    container: '(string|element|boolean)',
+    fallbackPlacement: '(string|array)'
+  };
+  var AttachmentMap = {
+    AUTO: 'auto',
+    TOP: 'top',
+    RIGHT: 'right',
+    BOTTOM: 'bottom',
+    LEFT: 'left'
+  };
+  var Default = {
+    animation: true,
+    template: '<div class="tooltip" role="tooltip">' + '<div class="arrow"></div>' + '<div 
class="tooltip-inner"></div></div>',
+    trigger: 'hover focus',
+    title: '',
+    delay: 0,
+    html: false,
+    selector: false,
+    placement: 'top',
+    offset: 0,
+    container: false,
+    fallbackPlacement: 'flip'
+  };
+  var HoverState = {
+    SHOW: 'show',
+    OUT: 'out'
+  };
+  var Event = {
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    INSERTED: "inserted" + EVENT_KEY,
+    CLICK: "click" + EVENT_KEY,
+    FOCUSIN: "focusin" + EVENT_KEY,
+    FOCUSOUT: "focusout" + EVENT_KEY,
+    MOUSEENTER: "mouseenter" + EVENT_KEY,
+    MOUSELEAVE: "mouseleave" + EVENT_KEY
+  };
+  var ClassName = {
+    FADE: 'fade',
+    SHOW: 'show'
+  };
+  var Selector = {
+    TOOLTIP: '.tooltip',
+    TOOLTIP_INNER: '.tooltip-inner',
+    ARROW: '.arrow'
+  };
+  var Trigger = {
+    HOVER: 'hover',
+    FOCUS: 'focus',
+    CLICK: 'click',
+    MANUAL: 'manual'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Tooltip =
+  /*#__PURE__*/
+  function () {
+    function Tooltip(element, config) {
+      // private
+      this._isEnabled = true;
+      this._timeout = 0;
+      this._hoverState = '';
+      this._activeTrigger = {};
+      this._popper = null; // protected
+
+      this.element = element;
+      this.config = this._getConfig(config);
+      this.tip = null;
+
+      this._setListeners();
+    } // getters
+
+
+    var _proto = Tooltip.prototype;
+
+    // public
+    _proto.enable = function enable() {
+      this._isEnabled = true;
+    };
+
+    _proto.disable = function disable() {
+      this._isEnabled = false;
+    };
+
+    _proto.toggleEnabled = function toggleEnabled() {
+      this._isEnabled = !this._isEnabled;
+    };
+
+    _proto.toggle = function toggle(event) {
+      if (!this._isEnabled) {
+        return;
+      }
+
+      if (event) {
+        var dataKey = this.constructor.DATA_KEY;
+        var context = $(event.currentTarget).data(dataKey);
+
+        if (!context) {
+          context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+          $(event.currentTarget).data(dataKey, context);
+        }
+
+        context._activeTrigger.click = !context._activeTrigger.click;
+
+        if (context._isWithActiveTrigger()) {
+          context._enter(null, context);
+        } else {
+          context._leave(null, context);
+        }
+      } else {
+        if ($(this.getTipElement()).hasClass(ClassName.SHOW)) {
+          this._leave(null, this);
+
+          return;
+        }
+
+        this._enter(null, this);
+      }
+    };
+
+    _proto.dispose = function dispose() {
+      clearTimeout(this._timeout);
+      $.removeData(this.element, this.constructor.DATA_KEY);
+      $(this.element).off(this.constructor.EVENT_KEY);
+      $(this.element).closest('.modal').off('hide.bs.modal');
+
+      if (this.tip) {
+        $(this.tip).remove();
+      }
+
+      this._isEnabled = null;
+      this._timeout = null;
+      this._hoverState = null;
+      this._activeTrigger = null;
+
+      if (this._popper !== null) {
+        this._popper.destroy();
+      }
+
+      this._popper = null;
+      this.element = null;
+      this.config = null;
+      this.tip = null;
+    };
+
+    _proto.show = function show() {
+      var _this = this;
+
+      if ($(this.element).css('display') === 'none') {
+        throw new Error('Please use show on visible elements');
+      }
+
+      var showEvent = $.Event(this.constructor.Event.SHOW);
+
+      if (this.isWithContent() && this._isEnabled) {
+        $(this.element).trigger(showEvent);
+        var isInTheDom = $.contains(this.element.ownerDocument.documentElement, this.element);
+
+        if (showEvent.isDefaultPrevented() || !isInTheDom) {
+          return;
+        }
+
+        var tip = this.getTipElement();
+        var tipId = Util.getUID(this.constructor.NAME);
+        tip.setAttribute('id', tipId);
+        this.element.setAttribute('aria-describedby', tipId);
+        this.setContent();
+
+        if (this.config.animation) {
+          $(tip).addClass(ClassName.FADE);
+        }
+
+        var placement = typeof this.config.placement === 'function' ? this.config.placement.call(this, tip, 
this.element) : this.config.placement;
+
+        var attachment = this._getAttachment(placement);
+
+        this.addAttachmentClass(attachment);
+        var container = this.config.container === false ? document.body : $(this.config.container);
+        $(tip).data(this.constructor.DATA_KEY, this);
+
+        if (!$.contains(this.element.ownerDocument.documentElement, this.tip)) {
+          $(tip).appendTo(container);
+        }
+
+        $(this.element).trigger(this.constructor.Event.INSERTED);
+        this._popper = new Popper(this.element, tip, {
+          placement: attachment,
+          modifiers: {
+            offset: {
+              offset: this.config.offset
+            },
+            flip: {
+              behavior: this.config.fallbackPlacement
+            },
+            arrow: {
+              element: Selector.ARROW
+            }
+          },
+          onCreate: function onCreate(data) {
+            if (data.originalPlacement !== data.placement) {
+              _this._handlePopperPlacementChange(data);
+            }
+          },
+          onUpdate: function onUpdate(data) {
+            _this._handlePopperPlacementChange(data);
+          }
+        });
+        $(tip).addClass(ClassName.SHOW); // if this is a touch-enabled device we add extra
+        // empty mouseover listeners to the body's immediate children;
+        // only needed because of broken event delegation on iOS
+        // https://www.quirksmode.org/blog/archives/2014/02/mouse_event_bub.html
+
+        if ('ontouchstart' in document.documentElement) {
+          $('body').children().on('mouseover', null, $.noop);
+        }
+
+        var complete = function complete() {
+          if (_this.config.animation) {
+            _this._fixTransition();
+          }
+
+          var prevHoverState = _this._hoverState;
+          _this._hoverState = null;
+          $(_this.element).trigger(_this.constructor.Event.SHOWN);
+
+          if (prevHoverState === HoverState.OUT) {
+            _this._leave(null, _this);
+          }
+        };
+
+        if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+          $(this.tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(Tooltip._TRANSITION_DURATION);
+        } else {
+          complete();
+        }
+      }
+    };
+
+    _proto.hide = function hide(callback) {
+      var _this2 = this;
+
+      var tip = this.getTipElement();
+      var hideEvent = $.Event(this.constructor.Event.HIDE);
+
+      var complete = function complete() {
+        if (_this2._hoverState !== HoverState.SHOW && tip.parentNode) {
+          tip.parentNode.removeChild(tip);
+        }
+
+        _this2._cleanTipClass();
+
+        _this2.element.removeAttribute('aria-describedby');
+
+        $(_this2.element).trigger(_this2.constructor.Event.HIDDEN);
+
+        if (_this2._popper !== null) {
+          _this2._popper.destroy();
+        }
+
+        if (callback) {
+          callback();
+        }
+      };
+
+      $(this.element).trigger(hideEvent);
+
+      if (hideEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      $(tip).removeClass(ClassName.SHOW); // if this is a touch-enabled device we remove the extra
+      // empty mouseover listeners we added for iOS support
+
+      if ('ontouchstart' in document.documentElement) {
+        $('body').children().off('mouseover', null, $.noop);
+      }
+
+      this._activeTrigger[Trigger.CLICK] = false;
+      this._activeTrigger[Trigger.FOCUS] = false;
+      this._activeTrigger[Trigger.HOVER] = false;
+
+      if (Util.supportsTransitionEnd() && $(this.tip).hasClass(ClassName.FADE)) {
+        $(tip).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+      } else {
+        complete();
+      }
+
+      this._hoverState = '';
+    };
+
+    _proto.update = function update() {
+      if (this._popper !== null) {
+        this._popper.scheduleUpdate();
+      }
+    }; // protected
+
+
+    _proto.isWithContent = function isWithContent() {
+      return Boolean(this.getTitle());
+    };
+
+    _proto.addAttachmentClass = function addAttachmentClass(attachment) {
+      $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
+    };
+
+    _proto.getTipElement = function getTipElement() {
+      this.tip = this.tip || $(this.config.template)[0];
+      return this.tip;
+    };
+
+    _proto.setContent = function setContent() {
+      var $tip = $(this.getTipElement());
+      this.setElementContent($tip.find(Selector.TOOLTIP_INNER), this.getTitle());
+      $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW);
+    };
+
+    _proto.setElementContent = function setElementContent($element, content) {
+      var html = this.config.html;
+
+      if (typeof content === 'object' && (content.nodeType || content.jquery)) {
+        // content is a DOM node or a jQuery
+        if (html) {
+          if (!$(content).parent().is($element)) {
+            $element.empty().append(content);
+          }
+        } else {
+          $element.text($(content).text());
+        }
+      } else {
+        $element[html ? 'html' : 'text'](content);
+      }
+    };
+
+    _proto.getTitle = function getTitle() {
+      var title = this.element.getAttribute('data-original-title');
+
+      if (!title) {
+        title = typeof this.config.title === 'function' ? this.config.title.call(this.element) : 
this.config.title;
+      }
+
+      return title;
+    }; // private
+
+
+    _proto._getAttachment = function _getAttachment(placement) {
+      return AttachmentMap[placement.toUpperCase()];
+    };
+
+    _proto._setListeners = function _setListeners() {
+      var _this3 = this;
+
+      var triggers = this.config.trigger.split(' ');
+      triggers.forEach(function (trigger) {
+        if (trigger === 'click') {
+          $(_this3.element).on(_this3.constructor.Event.CLICK, _this3.config.selector, function (event) {
+            return _this3.toggle(event);
+          });
+        } else if (trigger !== Trigger.MANUAL) {
+          var eventIn = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSEENTER : 
_this3.constructor.Event.FOCUSIN;
+          var eventOut = trigger === Trigger.HOVER ? _this3.constructor.Event.MOUSELEAVE : 
_this3.constructor.Event.FOCUSOUT;
+          $(_this3.element).on(eventIn, _this3.config.selector, function (event) {
+            return _this3._enter(event);
+          }).on(eventOut, _this3.config.selector, function (event) {
+            return _this3._leave(event);
+          });
+        }
+
+        $(_this3.element).closest('.modal').on('hide.bs.modal', function () {
+          return _this3.hide();
+        });
+      });
+
+      if (this.config.selector) {
+        this.config = $.extend({}, this.config, {
+          trigger: 'manual',
+          selector: ''
+        });
+      } else {
+        this._fixTitle();
+      }
+    };
+
+    _proto._fixTitle = function _fixTitle() {
+      var titleType = typeof this.element.getAttribute('data-original-title');
+
+      if (this.element.getAttribute('title') || titleType !== 'string') {
+        this.element.setAttribute('data-original-title', this.element.getAttribute('title') || '');
+        this.element.setAttribute('title', '');
+      }
+    };
+
+    _proto._enter = function _enter(event, context) {
+      var dataKey = this.constructor.DATA_KEY;
+      context = context || $(event.currentTarget).data(dataKey);
+
+      if (!context) {
+        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+        $(event.currentTarget).data(dataKey, context);
+      }
+
+      if (event) {
+        context._activeTrigger[event.type === 'focusin' ? Trigger.FOCUS : Trigger.HOVER] = true;
+      }
+
+      if ($(context.getTipElement()).hasClass(ClassName.SHOW) || context._hoverState === HoverState.SHOW) {
+        context._hoverState = HoverState.SHOW;
+        return;
+      }
+
+      clearTimeout(context._timeout);
+      context._hoverState = HoverState.SHOW;
+
+      if (!context.config.delay || !context.config.delay.show) {
+        context.show();
+        return;
+      }
+
+      context._timeout = setTimeout(function () {
+        if (context._hoverState === HoverState.SHOW) {
+          context.show();
+        }
+      }, context.config.delay.show);
+    };
+
+    _proto._leave = function _leave(event, context) {
+      var dataKey = this.constructor.DATA_KEY;
+      context = context || $(event.currentTarget).data(dataKey);
+
+      if (!context) {
+        context = new this.constructor(event.currentTarget, this._getDelegateConfig());
+        $(event.currentTarget).data(dataKey, context);
+      }
+
+      if (event) {
+        context._activeTrigger[event.type === 'focusout' ? Trigger.FOCUS : Trigger.HOVER] = false;
+      }
+
+      if (context._isWithActiveTrigger()) {
+        return;
+      }
+
+      clearTimeout(context._timeout);
+      context._hoverState = HoverState.OUT;
+
+      if (!context.config.delay || !context.config.delay.hide) {
+        context.hide();
+        return;
+      }
+
+      context._timeout = setTimeout(function () {
+        if (context._hoverState === HoverState.OUT) {
+          context.hide();
+        }
+      }, context.config.delay.hide);
+    };
+
+    _proto._isWithActiveTrigger = function _isWithActiveTrigger() {
+      for (var trigger in this._activeTrigger) {
+        if (this._activeTrigger[trigger]) {
+          return true;
+        }
+      }
+
+      return false;
+    };
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, this.constructor.Default, $(this.element).data(), config);
+
+      if (typeof config.delay === 'number') {
+        config.delay = {
+          show: config.delay,
+          hide: config.delay
+        };
+      }
+
+      if (typeof config.title === 'number') {
+        config.title = config.title.toString();
+      }
+
+      if (typeof config.content === 'number') {
+        config.content = config.content.toString();
+      }
+
+      Util.typeCheckConfig(NAME, config, this.constructor.DefaultType);
+      return config;
+    };
+
+    _proto._getDelegateConfig = function _getDelegateConfig() {
+      var config = {};
+
+      if (this.config) {
+        for (var key in this.config) {
+          if (this.constructor.Default[key] !== this.config[key]) {
+            config[key] = this.config[key];
+          }
+        }
+      }
+
+      return config;
+    };
+
+    _proto._cleanTipClass = function _cleanTipClass() {
+      var $tip = $(this.getTipElement());
+      var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
+
+      if (tabClass !== null && tabClass.length > 0) {
+        $tip.removeClass(tabClass.join(''));
+      }
+    };
+
+    _proto._handlePopperPlacementChange = function _handlePopperPlacementChange(data) {
+      this._cleanTipClass();
+
+      this.addAttachmentClass(this._getAttachment(data.placement));
+    };
+
+    _proto._fixTransition = function _fixTransition() {
+      var tip = this.getTipElement();
+      var initConfigAnimation = this.config.animation;
+
+      if (tip.getAttribute('x-placement') !== null) {
+        return;
+      }
+
+      $(tip).removeClass(ClassName.FADE);
+      this.config.animation = false;
+      this.hide();
+      this.show();
+      this.config.animation = initConfigAnimation;
+    }; // static
+
+
+    Tooltip._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = typeof config === 'object' && config;
+
+        if (!data && /dispose|hide/.test(config)) {
+          return;
+        }
+
+        if (!data) {
+          data = new Tooltip(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    createClass(Tooltip, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }, {
+      key: "NAME",
+      get: function get() {
+        return NAME;
+      }
+    }, {
+      key: "DATA_KEY",
+      get: function get() {
+        return DATA_KEY;
+      }
+    }, {
+      key: "Event",
+      get: function get() {
+        return Event;
+      }
+    }, {
+      key: "EVENT_KEY",
+      get: function get() {
+        return EVENT_KEY;
+      }
+    }, {
+      key: "DefaultType",
+      get: function get() {
+        return DefaultType;
+      }
+    }]);
+    return Tooltip;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+
+  $.fn[NAME] = Tooltip._jQueryInterface;
+  $.fn[NAME].Constructor = Tooltip;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Tooltip._jQueryInterface;
+  };
+
+  return Tooltip;
+}($, Popper);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): popover.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Popover = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'popover';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.popover';
+  var EVENT_KEY = "." + DATA_KEY;
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var CLASS_PREFIX = 'bs-popover';
+  var BSCLS_PREFIX_REGEX = new RegExp("(^|\\s)" + CLASS_PREFIX + "\\S+", 'g');
+  var Default = $.extend({}, Tooltip.Default, {
+    placement: 'right',
+    trigger: 'click',
+    content: '',
+    template: '<div class="popover" role="tooltip">' + '<div class="arrow"></div>' + '<h3 
class="popover-header"></h3>' + '<div class="popover-body"></div></div>'
+  });
+  var DefaultType = $.extend({}, Tooltip.DefaultType, {
+    content: '(string|element|function)'
+  });
+  var ClassName = {
+    FADE: 'fade',
+    SHOW: 'show'
+  };
+  var Selector = {
+    TITLE: '.popover-header',
+    CONTENT: '.popover-body'
+  };
+  var Event = {
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    INSERTED: "inserted" + EVENT_KEY,
+    CLICK: "click" + EVENT_KEY,
+    FOCUSIN: "focusin" + EVENT_KEY,
+    FOCUSOUT: "focusout" + EVENT_KEY,
+    MOUSEENTER: "mouseenter" + EVENT_KEY,
+    MOUSELEAVE: "mouseleave" + EVENT_KEY
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Popover =
+  /*#__PURE__*/
+  function (_Tooltip) {
+    inheritsLoose(Popover, _Tooltip);
+
+    function Popover() {
+      return _Tooltip.apply(this, arguments) || this;
+    }
+
+    var _proto = Popover.prototype;
+
+    // overrides
+    _proto.isWithContent = function isWithContent() {
+      return this.getTitle() || this._getContent();
+    };
+
+    _proto.addAttachmentClass = function addAttachmentClass(attachment) {
+      $(this.getTipElement()).addClass(CLASS_PREFIX + "-" + attachment);
+    };
+
+    _proto.getTipElement = function getTipElement() {
+      this.tip = this.tip || $(this.config.template)[0];
+      return this.tip;
+    };
+
+    _proto.setContent = function setContent() {
+      var $tip = $(this.getTipElement()); // we use append for html objects to maintain js events
+
+      this.setElementContent($tip.find(Selector.TITLE), this.getTitle());
+      this.setElementContent($tip.find(Selector.CONTENT), this._getContent());
+      $tip.removeClass(ClassName.FADE + " " + ClassName.SHOW);
+    }; // private
+
+
+    _proto._getContent = function _getContent() {
+      return this.element.getAttribute('data-content') || (typeof this.config.content === 'function' ? 
this.config.content.call(this.element) : this.config.content);
+    };
+
+    _proto._cleanTipClass = function _cleanTipClass() {
+      var $tip = $(this.getTipElement());
+      var tabClass = $tip.attr('class').match(BSCLS_PREFIX_REGEX);
+
+      if (tabClass !== null && tabClass.length > 0) {
+        $tip.removeClass(tabClass.join(''));
+      }
+    }; // static
+
+
+    Popover._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = typeof config === 'object' ? config : null;
+
+        if (!data && /destroy|hide/.test(config)) {
+          return;
+        }
+
+        if (!data) {
+          data = new Popover(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    createClass(Popover, null, [{
+      key: "VERSION",
+      // getters
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }, {
+      key: "NAME",
+      get: function get() {
+        return NAME;
+      }
+    }, {
+      key: "DATA_KEY",
+      get: function get() {
+        return DATA_KEY;
+      }
+    }, {
+      key: "Event",
+      get: function get() {
+        return Event;
+      }
+    }, {
+      key: "EVENT_KEY",
+      get: function get() {
+        return EVENT_KEY;
+      }
+    }, {
+      key: "DefaultType",
+      get: function get() {
+        return DefaultType;
+      }
+    }]);
+    return Popover;
+  }(Tooltip);
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+
+  $.fn[NAME] = Popover._jQueryInterface;
+  $.fn[NAME].Constructor = Popover;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Popover._jQueryInterface;
+  };
+
+  return Popover;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): scrollspy.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var ScrollSpy = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'scrollspy';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.scrollspy';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var Default = {
+    offset: 10,
+    method: 'auto',
+    target: ''
+  };
+  var DefaultType = {
+    offset: 'number',
+    method: 'string',
+    target: '(string|element)'
+  };
+  var Event = {
+    ACTIVATE: "activate" + EVENT_KEY,
+    SCROLL: "scroll" + EVENT_KEY,
+    LOAD_DATA_API: "load" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    DROPDOWN_ITEM: 'dropdown-item',
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active'
+  };
+  var Selector = {
+    DATA_SPY: '[data-spy="scroll"]',
+    ACTIVE: '.active',
+    NAV_LIST_GROUP: '.nav, .list-group',
+    NAV_LINKS: '.nav-link',
+    NAV_ITEMS: '.nav-item',
+    LIST_ITEMS: '.list-group-item',
+    DROPDOWN: '.dropdown',
+    DROPDOWN_ITEMS: '.dropdown-item',
+    DROPDOWN_TOGGLE: '.dropdown-toggle'
+  };
+  var OffsetMethod = {
+    OFFSET: 'offset',
+    POSITION: 'position'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var ScrollSpy =
+  /*#__PURE__*/
+  function () {
+    function ScrollSpy(element, config) {
+      var _this = this;
+
+      this._element = element;
+      this._scrollElement = element.tagName === 'BODY' ? window : element;
+      this._config = this._getConfig(config);
+      this._selector = this._config.target + " " + Selector.NAV_LINKS + "," + (this._config.target + " " + 
Selector.LIST_ITEMS + ",") + (this._config.target + " " + Selector.DROPDOWN_ITEMS);
+      this._offsets = [];
+      this._targets = [];
+      this._activeTarget = null;
+      this._scrollHeight = 0;
+      $(this._scrollElement).on(Event.SCROLL, function (event) {
+        return _this._process(event);
+      });
+      this.refresh();
+
+      this._process();
+    } // getters
+
+
+    var _proto = ScrollSpy.prototype;
+
+    // public
+    _proto.refresh = function refresh() {
+      var _this2 = this;
+
+      var autoMethod = this._scrollElement !== this._scrollElement.window ? OffsetMethod.POSITION : 
OffsetMethod.OFFSET;
+      var offsetMethod = this._config.method === 'auto' ? autoMethod : this._config.method;
+      var offsetBase = offsetMethod === OffsetMethod.POSITION ? this._getScrollTop() : 0;
+      this._offsets = [];
+      this._targets = [];
+      this._scrollHeight = this._getScrollHeight();
+      var targets = $.makeArray($(this._selector));
+      targets.map(function (element) {
+        var target;
+        var targetSelector = Util.getSelectorFromElement(element);
+
+        if (targetSelector) {
+          target = $(targetSelector)[0];
+        }
+
+        if (target) {
+          var targetBCR = target.getBoundingClientRect();
+
+          if (targetBCR.width || targetBCR.height) {
+            // todo (fat): remove sketch reliance on jQuery position/offset
+            return [$(target)[offsetMethod]().top + offsetBase, targetSelector];
+          }
+        }
+
+        return null;
+      }).filter(function (item) {
+        return item;
+      }).sort(function (a, b) {
+        return a[0] - b[0];
+      }).forEach(function (item) {
+        _this2._offsets.push(item[0]);
+
+        _this2._targets.push(item[1]);
+      });
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      $(this._scrollElement).off(EVENT_KEY);
+      this._element = null;
+      this._scrollElement = null;
+      this._config = null;
+      this._selector = null;
+      this._offsets = null;
+      this._targets = null;
+      this._activeTarget = null;
+      this._scrollHeight = null;
+    }; // private
+
+
+    _proto._getConfig = function _getConfig(config) {
+      config = $.extend({}, Default, config);
+
+      if (typeof config.target !== 'string') {
+        var id = $(config.target).attr('id');
+
+        if (!id) {
+          id = Util.getUID(NAME);
+          $(config.target).attr('id', id);
+        }
+
+        config.target = "#" + id;
+      }
+
+      Util.typeCheckConfig(NAME, config, DefaultType);
+      return config;
+    };
+
+    _proto._getScrollTop = function _getScrollTop() {
+      return this._scrollElement === window ? this._scrollElement.pageYOffset : 
this._scrollElement.scrollTop;
+    };
+
+    _proto._getScrollHeight = function _getScrollHeight() {
+      return this._scrollElement.scrollHeight || Math.max(document.body.scrollHeight, 
document.documentElement.scrollHeight);
+    };
+
+    _proto._getOffsetHeight = function _getOffsetHeight() {
+      return this._scrollElement === window ? window.innerHeight : 
this._scrollElement.getBoundingClientRect().height;
+    };
+
+    _proto._process = function _process() {
+      var scrollTop = this._getScrollTop() + this._config.offset;
+
+      var scrollHeight = this._getScrollHeight();
+
+      var maxScroll = this._config.offset + scrollHeight - this._getOffsetHeight();
+
+      if (this._scrollHeight !== scrollHeight) {
+        this.refresh();
+      }
+
+      if (scrollTop >= maxScroll) {
+        var target = this._targets[this._targets.length - 1];
+
+        if (this._activeTarget !== target) {
+          this._activate(target);
+        }
+
+        return;
+      }
+
+      if (this._activeTarget && scrollTop < this._offsets[0] && this._offsets[0] > 0) {
+        this._activeTarget = null;
+
+        this._clear();
+
+        return;
+      }
+
+      for (var i = this._offsets.length; i--;) {
+        var isActiveTarget = this._activeTarget !== this._targets[i] && scrollTop >= this._offsets[i] && 
(typeof this._offsets[i + 1] === 'undefined' || scrollTop < this._offsets[i + 1]);
+
+        if (isActiveTarget) {
+          this._activate(this._targets[i]);
+        }
+      }
+    };
+
+    _proto._activate = function _activate(target) {
+      this._activeTarget = target;
+
+      this._clear();
+
+      var queries = this._selector.split(','); // eslint-disable-next-line arrow-body-style
+
+
+      queries = queries.map(function (selector) {
+        return selector + "[data-target=\"" + target + "\"]," + (selector + "[href=\"" + target + "\"]");
+      });
+      var $link = $(queries.join(','));
+
+      if ($link.hasClass(ClassName.DROPDOWN_ITEM)) {
+        $link.closest(Selector.DROPDOWN).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
+        $link.addClass(ClassName.ACTIVE);
+      } else {
+        // Set triggered link as active
+        $link.addClass(ClassName.ACTIVE); // Set triggered links parents as active
+        // With both <ul> and <nav> markup a parent is the previous sibling of any nav ancestor
+
+        $link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_LINKS + ", " + 
Selector.LIST_ITEMS).addClass(ClassName.ACTIVE); // Handle special case when .nav-link is inside .nav-item
+
+        
$link.parents(Selector.NAV_LIST_GROUP).prev(Selector.NAV_ITEMS).children(Selector.NAV_LINKS).addClass(ClassName.ACTIVE);
+      }
+
+      $(this._scrollElement).trigger(Event.ACTIVATE, {
+        relatedTarget: target
+      });
+    };
+
+    _proto._clear = function _clear() {
+      $(this._selector).filter(Selector.ACTIVE).removeClass(ClassName.ACTIVE);
+    }; // static
+
+
+    ScrollSpy._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var data = $(this).data(DATA_KEY);
+
+        var _config = typeof config === 'object' && config;
+
+        if (!data) {
+          data = new ScrollSpy(this, _config);
+          $(this).data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    createClass(ScrollSpy, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }, {
+      key: "Default",
+      get: function get() {
+        return Default;
+      }
+    }]);
+    return ScrollSpy;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(window).on(Event.LOAD_DATA_API, function () {
+    var scrollSpys = $.makeArray($(Selector.DATA_SPY));
+
+    for (var i = scrollSpys.length; i--;) {
+      var $spy = $(scrollSpys[i]);
+
+      ScrollSpy._jQueryInterface.call($spy, $spy.data());
+    }
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = ScrollSpy._jQueryInterface;
+  $.fn[NAME].Constructor = ScrollSpy;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return ScrollSpy._jQueryInterface;
+  };
+
+  return ScrollSpy;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-beta.2): tab.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+var Tab = function () {
+  /**
+   * ------------------------------------------------------------------------
+   * Constants
+   * ------------------------------------------------------------------------
+   */
+  var NAME = 'tab';
+  var VERSION = '4.0.0-beta.2';
+  var DATA_KEY = 'bs.tab';
+  var EVENT_KEY = "." + DATA_KEY;
+  var DATA_API_KEY = '.data-api';
+  var JQUERY_NO_CONFLICT = $.fn[NAME];
+  var TRANSITION_DURATION = 150;
+  var Event = {
+    HIDE: "hide" + EVENT_KEY,
+    HIDDEN: "hidden" + EVENT_KEY,
+    SHOW: "show" + EVENT_KEY,
+    SHOWN: "shown" + EVENT_KEY,
+    CLICK_DATA_API: "click" + EVENT_KEY + DATA_API_KEY
+  };
+  var ClassName = {
+    DROPDOWN_MENU: 'dropdown-menu',
+    ACTIVE: 'active',
+    DISABLED: 'disabled',
+    FADE: 'fade',
+    SHOW: 'show'
+  };
+  var Selector = {
+    DROPDOWN: '.dropdown',
+    NAV_LIST_GROUP: '.nav, .list-group',
+    ACTIVE: '.active',
+    ACTIVE_UL: '> li > .active',
+    DATA_TOGGLE: '[data-toggle="tab"], [data-toggle="pill"], [data-toggle="list"]',
+    DROPDOWN_TOGGLE: '.dropdown-toggle',
+    DROPDOWN_ACTIVE_CHILD: '> .dropdown-menu .active'
+    /**
+     * ------------------------------------------------------------------------
+     * Class Definition
+     * ------------------------------------------------------------------------
+     */
+
+  };
+
+  var Tab =
+  /*#__PURE__*/
+  function () {
+    function Tab(element) {
+      this._element = element;
+    } // getters
+
+
+    var _proto = Tab.prototype;
+
+    // public
+    _proto.show = function show() {
+      var _this = this;
+
+      if (this._element.parentNode && this._element.parentNode.nodeType === Node.ELEMENT_NODE && 
$(this._element).hasClass(ClassName.ACTIVE) || $(this._element).hasClass(ClassName.DISABLED)) {
+        return;
+      }
+
+      var target;
+      var previous;
+      var listElement = $(this._element).closest(Selector.NAV_LIST_GROUP)[0];
+      var selector = Util.getSelectorFromElement(this._element);
+
+      if (listElement) {
+        var itemSelector = listElement.nodeName === 'UL' ? Selector.ACTIVE_UL : Selector.ACTIVE;
+        previous = $.makeArray($(listElement).find(itemSelector));
+        previous = previous[previous.length - 1];
+      }
+
+      var hideEvent = $.Event(Event.HIDE, {
+        relatedTarget: this._element
+      });
+      var showEvent = $.Event(Event.SHOW, {
+        relatedTarget: previous
+      });
+
+      if (previous) {
+        $(previous).trigger(hideEvent);
+      }
+
+      $(this._element).trigger(showEvent);
+
+      if (showEvent.isDefaultPrevented() || hideEvent.isDefaultPrevented()) {
+        return;
+      }
+
+      if (selector) {
+        target = $(selector)[0];
+      }
+
+      this._activate(this._element, listElement);
+
+      var complete = function complete() {
+        var hiddenEvent = $.Event(Event.HIDDEN, {
+          relatedTarget: _this._element
+        });
+        var shownEvent = $.Event(Event.SHOWN, {
+          relatedTarget: previous
+        });
+        $(previous).trigger(hiddenEvent);
+        $(_this._element).trigger(shownEvent);
+      };
+
+      if (target) {
+        this._activate(target, target.parentNode, complete);
+      } else {
+        complete();
+      }
+    };
+
+    _proto.dispose = function dispose() {
+      $.removeData(this._element, DATA_KEY);
+      this._element = null;
+    }; // private
+
+
+    _proto._activate = function _activate(element, container, callback) {
+      var _this2 = this;
+
+      var activeElements;
+
+      if (container.nodeName === 'UL') {
+        activeElements = $(container).find(Selector.ACTIVE_UL);
+      } else {
+        activeElements = $(container).children(Selector.ACTIVE);
+      }
+
+      var active = activeElements[0];
+      var isTransitioning = callback && Util.supportsTransitionEnd() && active && 
$(active).hasClass(ClassName.FADE);
+
+      var complete = function complete() {
+        return _this2._transitionComplete(element, active, isTransitioning, callback);
+      };
+
+      if (active && isTransitioning) {
+        $(active).one(Util.TRANSITION_END, complete).emulateTransitionEnd(TRANSITION_DURATION);
+      } else {
+        complete();
+      }
+
+      if (active) {
+        $(active).removeClass(ClassName.SHOW);
+      }
+    };
+
+    _proto._transitionComplete = function _transitionComplete(element, active, isTransitioning, callback) {
+      if (active) {
+        $(active).removeClass(ClassName.ACTIVE);
+        var dropdownChild = $(active.parentNode).find(Selector.DROPDOWN_ACTIVE_CHILD)[0];
+
+        if (dropdownChild) {
+          $(dropdownChild).removeClass(ClassName.ACTIVE);
+        }
+
+        if (active.getAttribute('role') === 'tab') {
+          active.setAttribute('aria-selected', false);
+        }
+      }
+
+      $(element).addClass(ClassName.ACTIVE);
+
+      if (element.getAttribute('role') === 'tab') {
+        element.setAttribute('aria-selected', true);
+      }
+
+      if (isTransitioning) {
+        Util.reflow(element);
+        $(element).addClass(ClassName.SHOW);
+      } else {
+        $(element).removeClass(ClassName.FADE);
+      }
+
+      if (element.parentNode && $(element.parentNode).hasClass(ClassName.DROPDOWN_MENU)) {
+        var dropdownElement = $(element).closest(Selector.DROPDOWN)[0];
+
+        if (dropdownElement) {
+          $(dropdownElement).find(Selector.DROPDOWN_TOGGLE).addClass(ClassName.ACTIVE);
+        }
+
+        element.setAttribute('aria-expanded', true);
+      }
+
+      if (callback) {
+        callback();
+      }
+    }; // static
+
+
+    Tab._jQueryInterface = function _jQueryInterface(config) {
+      return this.each(function () {
+        var $this = $(this);
+        var data = $this.data(DATA_KEY);
+
+        if (!data) {
+          data = new Tab(this);
+          $this.data(DATA_KEY, data);
+        }
+
+        if (typeof config === 'string') {
+          if (typeof data[config] === 'undefined') {
+            throw new Error("No method named \"" + config + "\"");
+          }
+
+          data[config]();
+        }
+      });
+    };
+
+    createClass(Tab, null, [{
+      key: "VERSION",
+      get: function get() {
+        return VERSION;
+      }
+    }]);
+    return Tab;
+  }();
+  /**
+   * ------------------------------------------------------------------------
+   * Data Api implementation
+   * ------------------------------------------------------------------------
+   */
+
+
+  $(document).on(Event.CLICK_DATA_API, Selector.DATA_TOGGLE, function (event) {
+    event.preventDefault();
+
+    Tab._jQueryInterface.call($(this), 'show');
+  });
+  /**
+   * ------------------------------------------------------------------------
+   * jQuery
+   * ------------------------------------------------------------------------
+   */
+
+  $.fn[NAME] = Tab._jQueryInterface;
+  $.fn[NAME].Constructor = Tab;
+
+  $.fn[NAME].noConflict = function () {
+    $.fn[NAME] = JQUERY_NO_CONFLICT;
+    return Tab._jQueryInterface;
+  };
+
+  return Tab;
+}($);
+
+/**
+ * --------------------------------------------------------------------------
+ * Bootstrap (v4.0.0-alpha.6): index.js
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ * --------------------------------------------------------------------------
+ */
+
+(function () {
+  if (typeof $ === 'undefined') {
+    throw new Error('Bootstrap\'s JavaScript requires jQuery. jQuery must be included before Bootstrap\'s 
JavaScript.');
+  }
+
+  var version = $.fn.jquery.split(' ')[0].split('.');
+  var minMajor = 1;
+  var ltMajor = 2;
+  var minMinor = 9;
+  var minPatch = 1;
+  var maxMajor = 4;
+
+  if (version[0] < ltMajor && version[1] < minMinor || version[0] === minMajor && version[1] === minMinor && 
version[2] < minPatch || version[0] >= maxMajor) {
+    throw new Error('Bootstrap\'s JavaScript requires at least jQuery v1.9.1 but less than v4.0.0');
+  }
+})($);
+
+exports.Util = Util;
+exports.Alert = Alert;
+exports.Button = Button;
+exports.Carousel = Carousel;
+exports.Collapse = Collapse;
+exports.Dropdown = Dropdown;
+exports.Modal = Modal;
+exports.Popover = Popover;
+exports.Scrollspy = ScrollSpy;
+exports.Tab = Tab;
+exports.Tooltip = Tooltip;
+
+return exports;
+
+}({},$,Popper));
+//# sourceMappingURL=bootstrap.js.map
diff --git a/src/js/guadec_map/.gitignore b/src/js/guadec_map/.gitignore
new file mode 100644
index 0000000..f36aabb
--- /dev/null
+++ b/src/js/guadec_map/.gitignore
@@ -0,0 +1,2 @@
+processing
+maki-svg
diff --git a/src/js/guadec_map/guadec-map.js b/src/js/guadec_map/guadec-map.js
new file mode 100644
index 0000000..5c79ea7
--- /dev/null
+++ b/src/js/guadec_map/guadec-map.js
@@ -0,0 +1,548 @@
+class GuadecMap {
+    constructor(options){
+        this.overpass_url = 'https://overpass-api.de/api/interpreter';
+        this.options = options;
+    }
+
+    /* Functions and helpers */
+    /* from https://www.npmjs.com/package/geojson-polygon-center */
+    static polygon_center(polygon) {
+        var minx = 1000,
+            miny = 1000,
+            maxx = -1000,
+            maxy = -1000,
+            polygon = polygon[0];
+        for (var i = 0; i < polygon.length; i++) {
+            var point = polygon[i]
+            var x = point[0]
+            var y = point[1]
+
+            if (x < minx) minx = x
+            else if (x > maxx) maxx = x
+            if (y < miny) miny = y
+            else if (y > maxy) maxy = y
+        }
+
+        return {
+            type: 'Point',
+            coordinates: [
+            minx + ((maxx - minx) / 2),
+            miny + ((maxy - miny) / 2)
+            ]
+        }
+    }
+
+    _get_routes(context, geometries){
+        // Data needed
+        var default_color = context.options.main_color;
+        var map = context.map;
+        var routes = context.options.routes;
+        var token = context.options.mapbox_token;
+
+        var get_coordinates = function(id){
+            var cand = geometries.filter(x => x.id == id );
+            if (cand.length ==1){
+                return cand[0];
+            } else {
+                return undefined;
+            }
+        };
+
+        var get_route = function(coords,method) {
+            var base_url = 'https://api.mapbox.com/directions/v5/mapbox/'+method;
+            var params = {
+                'overview': 'full',
+                'geometries': 'polyline6',
+                'access_token': token
+            };
+
+            // Transform to string
+            var coordinates = coords.map(c => c.coordinates).map( c => c.join(',')).join(';');
+            var params_str = Object.keys(params).map( p => `${p}=${params[p]}`).join('&');
+            // Final URL to get data from Mapbox
+            var url = `${base_url}/${coordinates}.json?${params_str}`
+    
+            return fetch(url).then(response => response.json())
+        };
+
+        var features_promises = routes.map(function(route){
+            return new Promise((resolve,reject) => {
+                // Get route data 
+                var coords = route.waypoints.map(get_coordinates);
+                // var from = get_coordinates(route['from']);
+                // var to = get_coordinates(route['to']);
+                var title = route['title'];
+                var color = route['color'];
+                var description = route['description'];
+                var method = route['method'] || 'driving';
+
+                if (coords.length >= 2){ 
+                    get_route(coords,method)
+                        .then(function(route){
+                            if (route.routes){
+                                var the_route = route.routes[0];
+                                resolve({
+                                            type : 'Feature',
+                                            geometry : polyline.toGeoJSON(the_route.geometry,6),
+                                            properties : {
+                                                distance : the_route['distance'],
+                                                duration: the_route['duration'],
+                                                name : title,
+                                                color : color,
+                                                description: description
+                                            }
+                                })                             
+                            } else {
+                                reject({
+                                    error : 'no routes found',
+                                    data : route
+                                });
+                            }
+                        });
+                } else {
+                    reject({
+                        'error' : 'bad data',
+                        'data' : route
+                    });
+                }
+            });
+        });
+
+        Promise.all(features_promises)
+            .then(function(values){
+                /* Route layer */
+                map.addLayer({
+                    'id': 'guadec_routes',
+                    'type': 'line',
+                    'source': {
+                        'type': 'geojson',
+                        'data':  {
+                            'type' : 'FeatureCollection',
+                            'features': values
+                        }
+                    },
+                    'layout': {},
+                    'paint': {    
+                        "line-color":[
+                            "case",
+                            ["has", 'color'], ["get", "color"],
+                            default_color,
+                        ],
+                        "line-width": 2
+                    }
+                },'boundary_country_inner');
+            })
+            .catch( error => console.error(error));
+    }
+    
+    /* This method initializes and returns a Mapbox map instance
+    with the interacitivity ready to be used */
+    init_map(){
+        var context = this;
+        var options = context.options;
+        var env = options.environment;
+
+        return new Promise(function(resolve,reject){
+            fetch(options.basemap_style)
+            .then(response => response.json())
+            .then(style =>{
+                if (env == 'DEV'){
+                    console.log('Using localhost sprite');
+                    style['sprite'] = 'http://localhost:8000/theme/js/guadec-map/sprite';
+                } else {
+                    console.log('Using guadecwebsite sprite');
+                    style['sprite'] = 'https://2018.guadec.org/theme/js/guadec-map/sprite';
+                }
+
+                var map = new mapboxgl.Map({
+                    container: 'map',
+                    style: options.tweak_style(style, options),
+                    center: options.center,
+                    zoom: options.zoom,
+                    attributionControl: true,
+                    hash: true
+                });
+                
+                /* Navigation control */
+                map.addControl(new mapboxgl.NavigationControl());
+                
+                /* Popup up singleton */
+                var tooltip = new mapboxgl.Popup({   
+                    closeButton: false,
+                    closeOnClick: true,
+                    anchor: "top",
+                    offset: [0, 8]
+                });
+                
+                // helper to render the properties
+                var get_properties_list = function(properties){
+                    return options.popup_properties
+                    .filter(function(key){
+                        return (Object.keys(properties).findIndex(x => x == key) > -1)
+                    })
+                    .map(function(key){
+                        if (key == 'website'){
+                            return `<li><a href="${properties[key]}">${key}</a></li>`
+                        } else if (key == 'wikidata'){
+                            return `<li><a 
href="https://www.wikidata.org/wiki/${properties[key]}";>${key}</a></li>`
+                        } else if (key == 'wikipedia'){
+                            return `<li><a 
href="https://en.wikipedia.org/wiki/${properties[key]}";>${key}</a></li>`
+                        } else if (key == 'picture') {
+                            return `<li><a href="${properties[key]}">Picture</a></li>`
+                        } else {
+                            return `<li><strong>${key}</strong>: ${properties[key]}</li>`
+                        }
+                    }).join('')
+                };
+        
+                var interactivity_handler = function(location,is_tooltip){
+                    if (! map.getLayer('guadec_icon') || ! map.getLayer('guadec_routes')) return;
+                    
+                    var features_icons = map.queryRenderedFeatures(location.point, { layers: ['guadec_icon'] 
});
+                    var features_routes = map.queryRenderedFeatures(location.point, { layers: 
['guadec_routes'] });
+                    
+                    // remove previous interactivity elements
+                    tooltip.remove();
+                    if (typeof map.getLayer('selected_route') !== "undefined" ){
+                        map.removeLayer('selected_route')
+                        map.removeSource('selected_route');   
+                    }
+                    
+                    if (features_icons != ''){
+                        var feature = features_icons[0];
+                        var popup = null;
+                        var popup_content = null;
+        
+                        if (is_tooltip){
+                            popup = tooltip;
+        
+                            if (feature.properties.cluster){
+                                popup_content = `<span>${feature.properties.point_count} points</span>`;
+                            } else {
+                                popup_content = `<span>${feature.properties.name}</span>`;
+                            }
+                        } else {
+                            popup = new mapboxgl.Popup({
+                                anchor:'bottom',
+                                closeOnClick: true,
+                                className:'guadec-popup'
+                            })
+                            
+                            if (feature.properties.cluster){
+                                popup_content = `<h3>${feature.properties.point_count} points</h3>`;
+                            } else {
+                                popup_content = `
+                                <h3>${feature.properties.name}</h3>
+                                <ul>
+                                    ${get_properties_list(feature.properties)}
+                                    </ul>
+                                    <p class="osm-source">
+                                    <a 
href="https://www.openstreetmap.org/${feature.properties.type}/${feature.properties.id}";>
+                                    Source
+                                    </a>
+                                    </p>
+                                `;
+                            }
+        
+                            
+                        }
+                        
+                        popup.setHTML(popup_content)
+                        .setLngLat(location.lngLat) 
+                            .addTo(map);
+                            
+                        } else if ( features_routes != '') {
+                            var feature = features_routes[0];
+                            var highlight_color = tinycolor(options.main_color).lighten(20);
+                            
+                            // Render the feature
+                            map.addSource('selected_route', {
+                            "type":"geojson",
+                            "data": feature.toJSON()
+                        });
+                        map.addLayer({
+                            "id": "selected_route",
+                            "type": "line",
+                            "source": "selected_route",
+                            "layout": {
+                                "line-join": "round",
+                                "line-cap": "round"
+                            },
+                            "paint": {
+                                "line-color": highlight_color.toHexString(),
+                                "line-width": 8
+                            }
+                        },'guadec_routes');
+        
+                        // Render the interactivity
+                        
+                        var popup = null;
+                        var popup_content = null;
+                        
+                        if (is_tooltip){
+                            popup = tooltip;
+                            popup_content = `<span>${feature.properties.name}</span>`;
+                        } else {
+                            popup = new mapboxgl.Popup({
+                                anchor:'bottom',
+                                closeOnClick: true,
+                                className:'guadec-popup'
+                            });
+                            popup_content = `
+                                <h3>${feature.properties.name}</h3> 
+                                <p>${feature.properties.description}</p>`;
+                                
+                        }
+        
+                        popup.setHTML(popup_content)
+                            .setLngLat(location.lngLat) 
+                            .addTo(map);
+                    }
+                }
+        
+                /* Popup interactivity */
+                map.on('click',function(location){
+                    interactivity_handler(location,false);
+                });
+                
+                
+                /* Popup interactivity */
+                map.on('mousemove',function(location){
+                    interactivity_handler(location,true);
+                });
+                
+                context.map = map;
+                resolve(map);
+            }).catch(error => reject(error));
+        })        
+    }
+    
+    /* Get data from OSM and return a promise when is parsed */
+    fetch_data(){
+        var context = this,
+            _get_osm_query= function(options){
+                var _get_ids = el => typeof el == "number" ? el : el['osm_id'];
+        
+                var ways = options.osm_ways.map(_get_ids).join(',');
+                var nodes = options.osm_nodes.map(_get_ids).join(',');
+        
+                return `[out:xml][timeout:300];
+                        (
+                            way(id:${ways});
+                            node(id:${nodes});
+                        )->.a;
+                        (.a; .a >;);out qt;`
+            };
+        
+        console.log('fetching osm data...')
+
+        return fetch(this.overpass_url,{
+            method: "POST",
+            body:  _get_osm_query(this.options)
+        })
+        .then(response => response.text())
+        .then(str => (new window.DOMParser()).parseFromString(str, "text/xml"))
+    }
+    
+    
+    /* transforms OSM data into geojson and adds that as
+        points and labels to the map */
+    process_osm_data(data){
+        console.log('loading data...');
+        var context = this,
+            // Convert to GeoJSON
+            geojson_data = osmtogeojson(data),
+            // Filter ways
+            polys_geojson = geojson_data.features.filter(function(feature){
+                return feature.properties.type == "way"
+            }),
+            // Filter points
+            points_geojson = geojson_data.features.filter(function(feature){
+                return feature.properties.type == "node"
+            }),
+            // Generate centroids for points
+            polys_geojson_points = polys_geojson.map(function(poly){
+                var copy = JSON.parse(JSON.stringify(poly));
+                copy['geometry'] = GuadecMap.polygon_center(copy.geometry.coordinates);
+                return copy
+            }),
+            // Get together both set of points
+            all_features = points_geojson.concat(polys_geojson_points),
+            // Get all properties out from the tags
+            points_geojson_props = all_features.map(function(feature){
+                    var properties = feature['properties'],
+                        tags = properties['tags'];
+                    Object.assign(properties, tags);
+                    delete properties['tags'];
+            
+                    if (properties['id'] == undefined){
+                        properties['id'] = String(feature['id'])
+                    } else {
+                        properties['id'] = String(properties['id'])
+                    };
+            
+                    // Override the name in Engish, if it exists
+                    if (properties['name:en'] != undefined){
+                        properties['name'] = properties['name:en']
+                    };
+            
+                    return feature
+                }
+            ),
+            /* takes a feature, and augment it with any custom properties 
+            passed on thi list of nodes and ways */
+            final_points = points_geojson_props.map(function(feature){
+                var options = context.options,
+                    /* filter checker */
+                    filter_node = function(node){
+                        return typeof node != "number" && node['osm_id'] == feat_id;
+                    },
+                    properties = feature['properties'],
+                    /* feature id */
+                    feat_id = properties['id'],
+                    /* candidates */
+                    candidate = options.osm_nodes.filter(filter_node)
+                                    .concat(options.osm_ways.filter(filter_node));
+
+                if (candidate.length == 1){
+                    properties = Object.assign(properties,candidate[0]);
+                };
+
+                return feature;
+            });
+
+        context.geojson_data = {
+            'type': 'FeatureCollection',
+            'features': final_points
+        }; 
+
+        // Build final geojson collection
+        return  context.geojson_data;         
+        }
+    
+    load_pois(){
+        var geojson_data = this.geojson_data;
+        var options = this.options;
+        var map = this.map;
+        var poi_color = tinycolor(options.main_color).darken().toHexString();
+
+        /* Icon layer */
+        map.addLayer({
+            'id': 'guadec_icon',
+            'type': 'symbol',
+            'source': {
+                'type': 'geojson',
+                'data': geojson_data,
+                'cluster' : true,
+                'clusterMaxZoom': 12
+            },
+            'layout': {
+                "symbol-placement": "point",
+                "text-field": '{name}' ,
+                "icon-image": [
+                    "case",
+                    ["has", 'icon'], ["get", "icon"],
+                    options.icon,
+                ],
+                "text-font": ["Open Sans Regular"],
+                "icon-allow-overlap": true,
+                "text-offset": [.3,.3],
+                "text-anchor": "top-left",
+                "text-max-width": 5,
+                "text-justify": "left",
+                "text-allow-overlap": false,
+                "text-optional": true,
+                "icon-size": {
+                    "stops": [
+                        [0, 0.1],
+                        [12, 0.7],
+                        [13,0.5],
+                        [20, 1.5],
+                    ]
+                },
+                "text-size": {
+                    "stops": [
+                        [0, 0],
+                        [9,0],
+                        [12, 15],
+                        [16, 20]
+                    ]
+                }
+            },
+            'paint': {
+                "text-color": poi_color,
+                "icon-opacity": 1,
+                "text-opacity": {
+                    "stops": [
+                        [0, 0],
+                        [9,0],
+                        [12, 1]
+                    ]
+                },
+                "text-halo-color": "white",
+                "text-halo-width": 2,
+                "text-halo-blur": 1
+            }
+        },'place_hamlet');
+    }
+    
+    load_routes(){
+        var routes = this.options.routes;
+        var data = this.geojson_data;
+        
+        // generate a list of nodes and geometries
+        var geom_ids = data.features.map(function(feature){
+            return {
+                'id'       : feature.properties['id' ], 
+                'coordinates' : feature.geometry.coordinates
+            }
+        });
+
+        var geom_ids_ids = geom_ids.map(x => x.id);
+        
+        // get the list of route waypoint ids not appearing in that list
+        var new_ids = Array.from(new Set (
+            [].concat.apply([], 
+                routes.map(function(route){
+                    return route.waypoints.filter( point => geom_ids_ids.indexOf(String(point)) == -1)
+                })
+            )
+            .filter(x => x != undefined)
+        ));
+        
+        // if needed get from overpass the rest of the geometries        
+        if (new_ids.length>0){
+            var overpass_url = this.overpass_url;
+            var get_osm_geoms = new Promise(function(resolve,reject){
+                var new_ids_str = new_ids.join(',');
+                var osm_query = `[out:json][timeout:300];node(id:${new_ids_str}); out skel qt;`;
+                
+                console.log('Fetching more data from OSM for the routes');
+                fetch(overpass_url,{ method: "POST", body:  osm_query })
+                .then(response => response.json())
+                .then(function(data){
+                    resolve(
+                        geom_ids.concat(
+                            data.elements.map(function(data){
+                                return { 'id': data.id, 'coordinates' : [data.lon, data.lat] }
+                            })
+                        )
+                    );
+                });      
+            });
+        } else {
+            var get_osm_geoms = Promise.resolve(geom_ids);
+        }
+        
+        /* 
+            When the data is here, all set up to get the routes
+            from Mapbox
+        */
+        var context = this;
+        get_osm_geoms.then(function(all_geom_ids){
+            context._get_routes(context,all_geom_ids);
+        });
+    }
+}
+
+window.GuadecMap = GuadecMap;
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/airport-45.svg 
b/src/js/guadec_map/maki-guadec-svg/airport-45.svg
new file mode 100644
index 0000000..023938f
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/airport-45.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="airport-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1231"
+     inkscape:window-height="575"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="0.11556944"
+     inkscape:cy="14.663949"
+     inkscape:window-x="189"
+     inkscape:window-y="383"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     id="path7712-0"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccsccc"
+     d="m 43.054279,20.631479 v 4.609092 L 25.240572,22.5 l -0.87205,13.079921 7.723476,4.733788 v 2.74057 l 
-9.591997,-1.868521 -9.591997,1.868521 v -2.74057 L 20.63148,35.579921 19.75943,22.5 1.9457214,25.240571 V 
20.631479 L 19.75943,14.278289 V 6.0565769 c 0,0 0,-4.1108558 2.740571,-4.1108558 2.740571,0 
2.740571,4.1108558 2.740571,4.1108558 v 7.7234751 z"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:2.74057055" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/bank-45.svg b/src/js/guadec_map/maki-guadec-svg/bank-45.svg
new file mode 100644
index 0000000..8aa9296
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/bank-45.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="bank-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     inkscape:connector-curvature="0"
+     id="rect5668"
+     d="m 3.9982959,9.6911273 c -1.5769145,0 -2.846416,1.2695017 -2.846416,2.8464157 v 19.924914 c 
0,1.576914 1.2695015,2.846416 2.846416,2.846416 H 41.001704 c 1.576915,0 2.846416,-1.269502 
2.846416,-2.846416 V 12.537543 c 0,-1.576914 -1.269501,-2.8464157 -2.846416,-2.8464157 z m 0,2.8464157 h 
4.269624 c 0.7858954,0 1.4232079,0.637313 1.4232079,1.423208 0,0.785896 -0.6373125,1.423209 
-1.4232079,1.423209 -0.7858955,0 -1.423208,-0.637313 -1.423208,-1.423209 l -1.423208,1.423209 c 0.7858954,0 
1.423208,0.637312 1.423208,1.423208 0,0.785895 -0.6373126,1.423208 -1.423208,1.423208 -0.7858955,0 
-1.423208,-0.637313 -1.423208,-1.423208 z m 18.5017031,0 c 3.930048,0 7.116042,4.460334 7.116042,9.962457 v 0 
c 0,5.502123 -3.185994,9.962457 -7.116042,9.962457 -3.930046,0 -7.116039,-4.460334 -7.116039,-9.962457 
0,-5.502123 3.185993,-9.962457 7.116039,-9.962457 z m 14.232082,0 h 4.269623 v 4.269625 c 0,0.785895 
-0.637312,1.423208 -1.423207,1.423208 -0.785896,0 -1.423208,-0.637313 -1.423208,
 -1.42320
 8 0,-0.785896 0.637312,-1.423208 1.423208,-1.423208 l -1.423208,-1.423209 c 0,0.785896 -0.637313,1.423209 
-1.423208,1.423209 -0.785896,0 -1.423208,-0.637313 -1.423208,-1.423209 0,-0.785895 0.637312,-1.423208 
1.423208,-1.423208 z m -14.232082,4.269625 c -0.919392,0 -1.518847,0.30969 -1.940117,0.711604 h 3.880519 c 
-0.421554,-0.401914 -1.021009,-0.711604 -1.940402,-0.711604 z m -2.490614,1.423208 c -0.129511,0.259023 
-0.175623,0.487021 -0.227997,0.711604 h 5.437223 c -0.05237,-0.224583 -0.09849,-0.452581 -0.227998,-0.711604 
z m -0.355802,1.423208 v 0.711604 h 5.692832 v -0.711604 z m 0,1.423208 v 0.711604 h 5.692832 v -0.711604 z m 
0,1.423208 v 0.711604 h 5.692832 V 22.5 Z m 0,1.423208 -0.711604,0.711605 h 5.692832 l 0.711604,-0.711605 z m 
-1.423208,1.423209 c 0,0 0.100479,0.291473 0.289196,0.711604 h 6.471042 L 23.923207,25.346417 Z M 
5.4215039,26.769625 c 0.7858954,0 1.423208,0.637312 1.423208,1.423208 0,0.785895 -0.6373126,1.423208 
-1.423208,1.423208 l 1.423208,1.423208 c 0
 ,-0.7858
 96 0.6373125,-1.423208 1.423208,-1.423208 0.7858954,0 1.4232079,0.637312 1.4232079,1.423208 0,0.785895 
-0.6373125,1.423208 -1.4232079,1.423208 h -4.269624 v -4.269624 c 0,-0.785896 0.6373125,-1.423208 
1.423208,-1.423208 z m 13.4871721,0 c 0.130651,0.243653 0.216613,0.45258 0.389105,0.711604 h 6.454533 c 
0.189572,-0.392521 0.305705,-0.711604 0.305705,-0.711604 z m 20.669821,0 c 0.785895,0 1.423207,0.637312 
1.423207,1.423208 v 4.269624 h -4.269623 c -0.785896,0 -1.423208,-0.637313 -1.423208,-1.423208 0,-0.785896 
0.637312,-1.423208 1.423208,-1.423208 0.785895,0 1.423208,0.637312 1.423208,1.423208 l 1.423208,-1.423208 c 
-0.785896,0 -1.423208,-0.637313 -1.423208,-1.423208 0,-0.785896 0.637312,-1.423208 1.423208,-1.423208 z m 
-19.735911,1.423208 c 0.223728,0.259593 0.468804,0.501823 0.739498,0.711604 h 4.041626 c 0.284927,-0.220028 
0.534273,-0.460266 0.722705,-0.711604 z"
+     style="stroke-width:2.846416;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/bar-45.svg b/src/js/guadec_map/maki-guadec-svg/bar-45.svg
new file mode 100644
index 0000000..afca105
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/bar-45.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="bar-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="861"
+     inkscape:window-width="1165"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="34.273567"
+     inkscape:cy="10.940374"
+     inkscape:window-x="125"
+     inkscape:window-y="233"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     id="path4"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sccsccsccszccccz"
+     d="m 22.607438,2.5365832 c -6.167321,0 -21.5856223,0.7709151 -20.0437922,2.3127453 L 
21.065608,24.122206 v 12.33464 c 0,3.083661 -9.250981,1.541831 -9.250981,6.167321 h 21.585621 c 0,-4.62549 
-9.25098,-3.08366 -9.25098,-6.167321 V 24.122206 L 42.651229,4.8493285 C 44.19306,3.3074983 
28.774758,2.5365832 22.607438,2.5365832 Z m 0,3.0836603 c 7.70915,0 14.647386,0.7709151 14.647386,0.7709151 L 
34.942079,8.7039039 H 10.272797 L 7.9600514,6.3911586 c 0,0 6.9382356,-0.7709151 14.6473866,-0.7709151 z"
+     style="stroke-width:3.08366036;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/bus-45.svg b/src/js/guadec_map/maki-guadec-svg/bus-45.svg
new file mode 100644
index 0000000..3946555
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/bus-45.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="bus-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1231"
+     inkscape:window-height="575"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="0.11556944"
+     inkscape:cy="14.663949"
+     inkscape:window-x="180"
+     inkscape:window-y="386"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     id="path8043"
+     d="m 12.167085,0.35803825 c -4.0257037,0 -8.8567845,2.19441595 -8.8567845,8.10720555 V 24.564223 
35.785178 c 0,0 0,2.952261 2.9522613,2.952261 V 41.6897 c 0,0 0,2.952262 2.9522619,2.952262 2.9522613,0 
2.9522613,-2.952262 2.9522613,-2.952262 V 38.737439 H 32.832916 V 41.6897 c 0,0 0,2.952262 2.952261,2.952262 
2.952261,0 2.952261,-2.952262 2.952261,-2.952262 v -2.952261 c 0,0 2.952262,0 2.952262,-2.952261 V 8.4652438 
c 0,-6.038851 -3.648995,-8.10720555 -7.674698,-8.10720555 z M 12.90515,4.7864301 h 19.189701 c 0.408887,0 
0.738065,0.3291771 0.738065,0.7380659 0,0.408888 -0.329178,0.7380652 -0.738065,0.7380652 H 12.90515 c 
-0.408888,0 -0.738065,-0.3291772 -0.738065,-0.7380652 0,-0.4088888 0.329177,-0.7380659 0.738065,-0.7380659 z 
M 9.2148237,9.2148233 H 35.785177 c 2.952261,0 2.952261,2.8542467 2.952261,2.8542467 v 8.954799 c 0,0 
0,2.952263 -2.952261,2.952263 H 9.2148237 c -2.9522619,0 -2.9522619,-2.952263 -2.9522619,-2.952263 v 
-8.856784 c 0,0 0,-2.9522617 2.9522619,-2.952
 2617 z m
  0,20.6658317 c 1.6305343,0 2.9522613,1.321727 2.9522613,2.952261 0,1.630534 -1.321727,2.952262 
-2.9522613,2.952262 -1.6305346,0 -2.9522619,-1.321728 -2.9522619,-2.952262 0,-1.630534 1.3217273,-2.952261 
2.9522619,-2.952261 z m 26.5703533,0 c 1.630534,0 2.952261,1.321727 2.952261,2.952261 0,1.630534 
-1.321727,2.952262 -2.952261,2.952262 -1.630534,0 -2.952261,-1.321728 -2.952261,-2.952262 0,-1.630534 
1.321727,-2.952261 2.952261,-2.952261 z"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:2.95226145"
+     inkscape:connector-curvature="0" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/cafe-45.svg b/src/js/guadec_map/maki-guadec-svg/cafe-45.svg
new file mode 100644
index 0000000..7c9f9d1
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/cafe-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="cafe-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="101"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="M 36.663575,11.877319 H 29.581787 V 4.7955319 H 1.2546384 V 18.959106 c 0.047094,7.822188 
6.4263677,14.124979 14.2485566,14.077885 4.99443,-0.0301 9.603611,-2.688247 12.131101,-6.996098 h 9.029279 c 
3.911271,0 7.081787,-3.170516 7.081787,-7.081787 0,-3.911271 -3.170516,-7.081787 -7.081787,-7.081787 z m 
0,10.622681 h -7.577513 c 0.314077,-1.154686 0.480853,-2.344426 0.495725,-3.540894 v -3.540893 h 7.081788 c 
1.955635,0 3.540893,1.585258 3.540893,3.540893 0,1.955636 -1.585258,3.540894 -3.540893,3.540894 z m 
-7.081788,15.934021 c 0,0.977641 -0.792806,1.770447 -1.770447,1.770447 H 3.0250852 c -0.9776407,0 
-1.7704468,-0.792806 -1.7704468,-1.770447 0,-0.977641 0.7928061,-1.770447 1.7704468,-1.770447 H 27.81134 c 
0.977641,0 1.770447,0.792806 1.770447,1.770447 z"
+     id="path2"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:3.54089355" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/circle-11.svg b/src/js/guadec_map/maki-guadec-svg/circle-11.svg
new file mode 100644
index 0000000..8b47638
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/circle-11.svg
@@ -0,0 +1,7 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg"; 
xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px"
+        width="11px" height="11px" viewBox="0 0 11 11" style="enable-background:new 0 0 11 11;" 
xml:space="preserve">
+<path d="M10,5.5C10,7.9853,7.9853,10,5.5,10S1,7.9853,1,5.5S3.0147,1,5.5,1S10,3.0147,10,5.5z"/>
+</svg>
diff --git a/src/js/guadec_map/maki-guadec-svg/circle-45.svg b/src/js/guadec_map/maki-guadec-svg/circle-45.svg
new file mode 100644
index 0000000..6128608
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/circle-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="circle-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 44.004441,22.500001 c 0,11.876664 -9.627777,21.504441 -21.504441,21.504441 -11.876664,0 
-21.50444145,-9.627777 -21.50444145,-21.504441 0,-11.876665 9.62777745,-21.5044425 21.50444145,-21.5044425 
11.876664,0 21.504441,9.6277775 21.504441,21.5044425 z"
+     id="path2"
+     style="stroke-width:4.77876472;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/gnome-guadec-blue.svg 
b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-blue.svg
new file mode 100644
index 0000000..7801a9f
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-blue.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="gnome-guadec-blue.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="761"
+     inkscape:window-width="1554"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="56.424947"
+     inkscape:cy="10.940374"
+     inkscape:window-x="229"
+     inkscape:window-y="277"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><g
+     style="fill:#4a86cf;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+     id="g1365"
+     transform="matrix(0.36909777,0,0,0.36909777,4.7445693,0.67524886)"><g
+       id="g1367"
+       style="fill:#4a86cf;fill-opacity:1"><path
+         d="M 86.068,0 C 61.466,0 56.851,35.041 70.691,35.041 84.529,35.041 110.671,0 86.068,0 Z"
+         id="path1369"
+         style="fill:#4a86cf;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 32.976,6.171 37.845,30.249 
45.217,30.699 Z"
+         id="path1371"
+         style="fill:#4a86cf;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 -5.7,35.89 6.204,50.759 11.445,48.453 
Z"
+         id="path1373"
+         style="fill:#4a86cf;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 10.539,18.961 19.978,37.916 
26.212,36.642 Z"
+         id="path1375"
+         style="fill:#4a86cf;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="m 58.791,93.913 c 1.107,8.454 -6.202,12.629 -13.36,7.179 C 22.644,83.743 83.16,75.088 
79.171,51.386 75.86,31.712 15.495,37.769 8.621,68.553 3.968,89.374 27.774,118.26 52.614,118.26 c 12.22,0 
26.315,-11.034 28.952,-25.012 C 83.58,82.589 57.867,86.86 58.791,93.913 Z"
+         id="newshape"
+         style="fill:#4a86cf;fill-opacity:1"
+         inkscape:connector-curvature="0" /></g></g></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/gnome-guadec-red.svg 
b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-red.svg
new file mode 100644
index 0000000..b147cf2
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-red.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="gnome-guadec-red.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="761"
+     inkscape:window-width="1554"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="56.424947"
+     inkscape:cy="10.940374"
+     inkscape:window-x="328"
+     inkscape:window-y="388"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><g
+     style="fill:#cf5e4a;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+     id="g1365"
+     transform="matrix(0.36909777,0,0,0.36909777,4.7445693,0.67524886)"><g
+       id="g1367"
+       style="fill:#cf5e4a;fill-opacity:1"><path
+         d="M 86.068,0 C 61.466,0 56.851,35.041 70.691,35.041 84.529,35.041 110.671,0 86.068,0 Z"
+         id="path1369"
+         style="fill:#cf5e4a;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 32.976,6.171 37.845,30.249 
45.217,30.699 Z"
+         id="path1371"
+         style="fill:#cf5e4a;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 -5.7,35.89 6.204,50.759 11.445,48.453 
Z"
+         id="path1373"
+         style="fill:#cf5e4a;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 10.539,18.961 19.978,37.916 
26.212,36.642 Z"
+         id="path1375"
+         style="fill:#cf5e4a;fill-opacity:1"
+         inkscape:connector-curvature="0" /><path
+         d="m 58.791,93.913 c 1.107,8.454 -6.202,12.629 -13.36,7.179 C 22.644,83.743 83.16,75.088 
79.171,51.386 75.86,31.712 15.495,37.769 8.621,68.553 3.968,89.374 27.774,118.26 52.614,118.26 c 12.22,0 
26.315,-11.034 28.952,-25.012 C 83.58,82.589 57.867,86.86 58.791,93.913 Z"
+         id="newshape"
+         style="fill:#cf5e4a;fill-opacity:1"
+         inkscape:connector-curvature="0" /></g></g></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/gnome-guadec-yellow.svg 
b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-yellow.svg
new file mode 100644
index 0000000..424042a
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/gnome-guadec-yellow.svg
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="gnome-guadec-yellow.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="761"
+     inkscape:window-width="1554"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="56.424947"
+     inkscape:cy="10.940374"
+     inkscape:window-x="328"
+     inkscape:window-y="388"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><g
+     style="fill:#cfc84a;fill-opacity:0.96862745;fill-rule:nonzero;stroke:none;stroke-miterlimit:4"
+     id="g1365"
+     transform="matrix(0.36909777,0,0,0.36909777,4.7445693,0.67524886)"><g
+       id="g1367"
+       style="fill:#cfc84a;fill-opacity:0.96862745"><path
+         d="M 86.068,0 C 61.466,0 56.851,35.041 70.691,35.041 84.529,35.041 110.671,0 86.068,0 Z"
+         id="path1369"
+         style="fill:#cfc84a;fill-opacity:0.96862745"
+         inkscape:connector-curvature="0" /><path
+         d="M 45.217,30.699 C 52.586,31.149 60.671,2.577 46.821,4.374 32.976,6.171 37.845,30.249 
45.217,30.699 Z"
+         id="path1371"
+         style="fill:#cfc84a;fill-opacity:0.96862745"
+         inkscape:connector-curvature="0" /><path
+         d="M 11.445,48.453 C 16.686,46.146 12.12,23.581 3.208,29.735 -5.7,35.89 6.204,50.759 11.445,48.453 
Z"
+         id="path1373"
+         style="fill:#cfc84a;fill-opacity:0.96862745"
+         inkscape:connector-curvature="0" /><path
+         d="M 26.212,36.642 C 32.451,35.37 32.793,9.778 21.667,14.369 10.539,18.961 19.978,37.916 
26.212,36.642 Z"
+         id="path1375"
+         style="fill:#cfc84a;fill-opacity:0.96862745"
+         inkscape:connector-curvature="0" /><path
+         d="m 58.791,93.913 c 1.107,8.454 -6.202,12.629 -13.36,7.179 C 22.644,83.743 83.16,75.088 
79.171,51.386 75.86,31.712 15.495,37.769 8.621,68.553 3.968,89.374 27.774,118.26 52.614,118.26 c 12.22,0 
26.315,-11.034 28.952,-25.012 C 83.58,82.589 57.867,86.86 58.791,93.913 Z"
+         id="newshape"
+         style="fill:#cfc84a;fill-opacity:0.96862745"
+         inkscape:connector-curvature="0" /></g></g></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/home-45.svg b/src/js/guadec_map/maki-guadec-svg/home-45.svg
new file mode 100644
index 0000000..2bb26e8
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/home-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="home-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 4.486945,42.969736 c 0,0.45228 0.3666529,0.818933 0.8189336,0.818933 H 17.586606 v -9.827203 h 
9.827203 v 9.827203 h 12.280729 c 0.452281,0 0.818934,-0.366653 0.818934,-0.818933 V 24.137213 H 4.486945 c 
0,0 0,18.832523 0,18.832523 z M 43.566456,19.482722 40.513799,16.800223 V 4.4870649 c 0,-1.8091225 
-1.466579,-3.2757343 -3.275734,-3.2757343 -1.809155,0 -3.275734,1.4666118 -3.275734,3.2757343 V 11.038534 L 
23.095736,1.5061467 C 22.786179,1.1775905 22.269137,1.1614739 21.93973,1.4701136 L 21.903697,1.5061467 
1.4333055,19.401484 c -0.3092294,0.330063 -0.2923266,0.848317 0.037736,1.157546 0.1489149,0.139514 
0.3445745,0.218393 0.54862,0.22121 l 5.7430174,0.08189 H 42.966342 c 0.45228,0.0015 0.820145,-0.363934 
0.821652,-0.816215 6.88e-4,-0.209025 -0.07855,-0.410384 -0.221538,-0.562869 z"
+     id="path2"
+     style="stroke-width:3.27573442;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/hospital-45.svg 
b/src/js/guadec_map/maki-guadec-svg/hospital-45.svg
new file mode 100644
index 0000000..329817c
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/hospital-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="hospital-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     id="rect4194"
+     inkscape:connector-curvature="0"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:3.23518443"
+     d="m 20.882408,1.4713012 c -1.94111,0 -3.235184,1.2940738 -3.235184,3.2351845 V 17.647224 H 4.7064856 c 
-1.9411107,0 -3.2351845,1.294074 -3.2351845,3.235184 v 3.235185 c 0,1.941111 1.2940738,3.235184 
3.2351845,3.235184 H 17.647224 v 12.940737 c 0,1.941111 1.294074,3.235185 3.235184,3.235185 h 3.235185 c 
1.94111,0 3.235184,-1.294074 3.235184,-3.235185 V 27.352777 h 12.940738 c 1.94111,0 3.235184,-1.294073 
3.235184,-3.235184 v -3.235185 c 0,-1.94111 -1.294074,-3.235184 -3.235184,-3.235184 H 27.352777 V 4.7064857 c 
0,-1.9411107 -1.294074,-3.2351845 -3.235184,-3.2351845 z" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/karaoke-45.svg 
b/src/js/guadec_map/maki-guadec-svg/karaoke-45.svg
new file mode 100644
index 0000000..656545d
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/karaoke-45.svg
@@ -0,0 +1,55 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="karaoke-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><g
+     transform="matrix(3.976542,0,0,3.976542,-7.8045513,-7.0363826)"
+     id="g8"
+     style="fill:#4a86cf;fill-opacity:1"><path
+       inkscape:connector-curvature="0"
+       d="M 12.1,2.952 A 2.988,2.988 0 0 0 6.99,4.917 l 3.142,3.142 A 2.988,2.988 0 0 0 12.1,2.952 Z"
+       id="path4"
+       style="fill:#4a86cf;fill-opacity:1" /><path
+       inkscape:connector-curvature="0"
+       d="M 4.672,8.255 2.55,10.377 a 1,1 0 0 0 0,1.414 l 0.707,0.707 a 1,1 0 0 0 1.414,0 L 6.792,10.377 
8.914,8.255 6.793,6.134 Z M 5.413,10.342 4.706,9.635 6.793,7.548 7.5,8.255 Z"
+       id="path6"
+       style="fill:#4a86cf;fill-opacity:1" /></g></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/lodging-45.svg 
b/src/js/guadec_map/maki-guadec-svg/lodging-45.svg
new file mode 100644
index 0000000..4c9a9f4
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/lodging-45.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="lodging-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     inkscape:connector-curvature="0"
+     id="rect6507"
+     style="fill:#4a86cf;stroke-width:2.78089261;fill-opacity:1"
+     d="m 3.0337513,7.9003135 c -0.8342678,0 -1.3904463,0.556179 -1.3904463,1.390446 v 20.8566945 5.561785 c 
0,0.834268 0.5561785,1.390447 1.3904463,1.390447 0.8342678,0 1.3904463,-0.556179 1.3904463,-1.390447 V 
31.5379 H 40.575802 v 4.171339 c 0,0.834268 0.556178,1.390447 1.390446,1.390447 0.834268,0 1.390447,-0.556179 
1.390447,-1.390447 v -5.561785 c 0,-0.834268 -0.556179,-1.390446 -1.390447,-1.390446 H 4.4241976 V 9.2907595 
c 0,-0.834267 -0.5561785,-1.390446 -1.3904463,-1.390446 z m 8.3426777,1.390446 c -2.2247139,0 
-4.1713389,1.9466255 -4.1713389,4.1713395 v 0 c 0,2.224713 1.946625,4.171338 4.1713389,4.171338 v 0 c 
2.224714,0 4.171339,-1.946625 4.171339,-4.171338 v 0 c 0,-2.224715 -1.946625,-4.1713395 -4.171339,-4.1713395 
z m 9.733124,2.7808925 c -4.171339,0 -4.171339,4.171339 -4.171339,4.171339 V 20.41433 H 8.5955366 c 
-0.8342678,0 -1.3904464,0.556178 -1.3904464,1.390446 v 2.780893 c 0,0.834268 0.5561786,1.390446 
1.3904464,1.390446 h 9.7331244 25.028034 v -6.952232 c 0,
 -6.95223
 1 -6.952232,-6.952231 -6.952232,-6.952231 z" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/marker-45.svg b/src/js/guadec_map/maki-guadec-svg/marker-45.svg
new file mode 100644
index 0000000..f8a35b9
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/marker-45.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="marker-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     id="path4133"
+     inkscape:connector-curvature="0"
+     d="m 22.499999,2.1221302 c -6.608951,0 -14.3196662,4.0388936 -14.3196662,14.3196638 0,6.976025 
11.0151902,22.397182 14.3196662,26.436076 2.937402,-4.038894 14.319668,-19.092706 14.319668,-26.436076 
0,-10.2807702 -7.710717,-14.3196638 -14.319668,-14.3196638 z"
+     style="stroke-width:2.71704936;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/music-45.svg b/src/js/guadec_map/maki-guadec-svg/music-45.svg
new file mode 100644
index 0000000..486ee78
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/music-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="music-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 41.790828,1.6016021 c -0.258497,0.00257 -0.512493,0.068804 -0.739482,0.1929083 L 
12.854586,9.639447 c -0.8877,0 -1.607569,0.71987 -1.607569,1.607569 v 20.191069 c -0.973866,-0.578082 
-2.0827665,-0.888343 -3.2151381,-0.900239 -3.5514414,0 -6.4302759,2.878835 -6.4302759,6.430276 0,3.551442 
2.8788345,6.430276 6.4302759,6.430276 3.5514411,0 6.4302761,-2.878834 6.4302761,-6.430276 V 22.049881 l 
25.721104,-7.137607 v 11.703103 c -0.973866,-0.578082 -2.082767,-0.888343 -3.215138,-0.900239 -3.551442,0 
-6.430276,2.878835 -6.430276,6.430277 0,3.551442 2.878834,6.430276 6.430276,6.430276 3.551441,0 
6.430276,-2.878834 6.430276,-6.430276 V 3.2091711 c 0,-0.8876996 -0.71987,-1.607569 -1.607569,-1.607569 z M 
40.183259,11.697136 14.462155,18.834743 V 12.404466 L 40.183259,5.2668594 c 0,0 0,6.4302766 0,6.4302766 z"
+     id="path2"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:3.21513796" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/park-45.svg b/src/js/guadec_map/maki-guadec-svg/park-45.svg
new file mode 100644
index 0000000..c27e65f
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/park-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="park-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 41.727638,16.833971 c 0.03628,-2.20317 -1.21924,-4.224322 -3.210216,-5.168447 C 
38.348886,9.5808101 36.595787,7.9821229 34.504653,8.0058785 34.187484,8.0312392 33.874809,8.0960855 
33.573691,8.1984914 33.378831,6.0797494 31.503423,4.5202268 29.385002,4.7150869 28.55452,4.79149 
27.771548,5.135304 27.153261,5.6945235 v 0 c 0,-2.2163326 -1.796437,-4.012769 -4.012769,-4.012769 -2.216333,0 
-4.012769,1.7964364 -4.012769,4.012769 0,0 0.128408,0.064204 0.128408,0.1605108 C 17.614427,4.4467129 
15.141919,4.6361156 13.733598,6.2781407 13.258165,6.8325448 12.947095,7.5086162 12.835701,8.2305936 
12.327524,8.0684777 11.795912,7.9927166 11.262695,8.0058785 8.6033527,7.983728 6.4293949,10.12141 
6.4072444,12.780753 c -0.00546,0.641401 0.1174939,1.277024 0.3611492,1.870272 -2.5440955,0.711063 
-4.0301042,3.35018 -3.3190415,5.894276 0.4500722,1.610566 1.7084766,2.868969 3.3190415,3.319041 
0.8131476,2.513278 3.5100494,3.891744 6.0233274,3.078597 1.718428,-0.55601 2.977153,-2.032388 3.25
 4195,-3.
 816946 0.587469,0.510745 1.313941,0.834977 2.08664,0.930962 V 40.10803 l -5.296855,3.210215 H 28.886777 L 
23.750433,40.10803 v -6.420429 c 2.369459,-2.861907 5.430079,-5.071818 8.892295,-6.42043 2.572025,0.6032 
5.145975,-0.992598 5.749175,-3.564303 0.09117,-0.388756 0.133545,-0.787465 0.125519,-1.186816 
0.0093,-0.171105 0.0093,-0.34253 0,-0.513635 1.990976,-0.944123 3.246491,-2.965274 3.210216,-5.168446 z m 
-17.977205,14.47807 v -11.04314 c 0.867721,1.543151 2.499152,2.499795 4.269586,2.503968 h 0.89886 c 
0.05008,1.409606 0.71973,2.725473 1.829822,3.595441 -2.618572,1.200621 -4.991563,2.876995 -6.998268,4.943731 
z"
+     id="path2"
+     style="stroke-width:3.21021533;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/parking-45.svg 
b/src/js/guadec_map/maki-guadec-svg/parking-45.svg
new file mode 100644
index 0000000..8982332
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/parking-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="parking-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="765"
+     inkscape:window-width="1255"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="12.122187"
+     inkscape:cy="10.940374"
+     inkscape:window-x="368"
+     inkscape:window-y="32"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 33.915216,25.096856 c -2.834411,2.107075 -6.315575,3.158828 -9.842532,2.973575 h -8.17733 v 
13.76765 H 7.5990814 V 3.1816093 H 24.607928 c 3.361626,-0.1799013 6.672701,0.8777992 9.307288,2.9735758 
2.474312,2.4225713 3.729755,5.8285039 3.419611,9.2775529 0.377941,3.572452 -0.878691,7.124387 
-3.419611,9.664118 z M 27.670709,11.210262 C 26.40813,10.286075 24.861276,9.8334969 23.299555,9.9316249 H 
15.895354 V 21.29068 h 7.404201 c 1.580455,0.09694 3.140094,-0.40173 4.371154,-1.39758 1.128472,-1.17367 
1.692856,-2.779103 1.546259,-4.400891 0.160573,-1.587889 -0.408272,-3.162991 -1.546259,-4.281947 z"
+     id="path2-3"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:2.97357464" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/rail-45.svg b/src/js/guadec_map/maki-guadec-svg/rail-45.svg
new file mode 100644
index 0000000..4481800
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/rail-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="rail-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     d="m 8.7438885,1.1016028 c -1.6883335,0 -3.0569138,1.3685803 -3.0569138,3.0569138 V 28.613828 c 
0,1.688333 1.3685803,3.056914 3.0569138,3.056914 H 36.256111 c 1.688334,0 3.056914,-1.368581 
3.056914,-3.056914 V 4.1585166 c 0,-1.6883335 -1.36858,-3.0569138 -3.056914,-3.0569138 z M 17.1504,2.6300597 
h 0.02996 10.699198 c 0.42216,0 0.764229,0.3420687 0.764229,0.7642284 0,0.4221598 -0.342069,0.7642285 
-0.764229,0.7642285 H 17.150492 c -0.42216,0 -0.764229,-0.3420687 -0.764229,-0.7642285 0,-0.4221597 
0.342069,-0.7642284 0.764229,-0.7642284 z M 10.272344,7.2154304 H 20.971542 V 19.443085 H 10.272344 c 
-0.8440125,0 -1.5284555,-0.684443 -1.5284555,-1.528456 V 8.7438873 c 0,-0.8440139 0.684443,-1.5284569 
1.5284555,-1.5284569 z m 13.756112,0 h 10.699198 c 0.844014,0 1.528457,0.684443 1.528457,1.5284569 v 
9.1707417 c 0,0.844013 -0.684443,1.528456 -1.528457,1.528456 H 24.028456 Z M 14.857715,22.499999 c 1.688333,0 
3.056914,1.368581 3.056914,3.056914 0,1.688334 -1.368581,3.056915 -3.
 056914,3
 .056915 -1.688333,0 -3.056914,-1.368581 -3.056914,-3.056915 0,-1.688333 1.368581,-3.056914 
3.056914,-3.056914 z m 15.284569,0 c 1.688333,0 3.056913,1.368581 3.056913,3.056914 0,1.688334 
-1.36858,3.056915 -3.056913,3.056915 -1.688334,0 -3.056914,-1.368581 -3.056914,-3.056915 0,-1.688333 
1.36858,-3.056914 3.056914,-3.056914 z m 1.36128,12.209746 c -0.197813,0.01681 -0.39841,0.07471 
-0.585111,0.173143 -0.682609,0.359494 -0.989444,1.171229 -0.716465,1.892661 l 0.519437,1.00902 H 14.278574 l 
0.394054,-0.823933 c 0.29866,-0.789601 -0.100022,-1.671618 -0.889608,-1.970276 -0.721431,-0.272676 
-1.533167,0.03415 -1.89266,0.716462 l -3.0569134,6.113827 c -0.064807,0.176078 -0.093838,0.361902 
-0.089558,0.549291 0,0.844014 0.684443,1.528457 1.5284564,1.528457 0.550855,-0.0031 1.054904,-0.307422 
1.313519,-0.794083 v -0.15523 h 0.214931 l 0.949315,-2.107601 h 19.499766 l 0.949315,2.107598 v 0.15523 c 
0.258615,0.486661 0.762664,0.791026 1.313519,0.794083 0.844011,0 1.528457,-0.684443 1.52845
 7,-1.528
 457 0.06083,-0.240885 0.06083,-0.49349 0,-0.734375 L 32.984253,35.521735 C 32.6892,34.961632 
32.097055,34.659202 31.503564,34.709745 Z"
+     id="path3"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:3.05691385" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/restaurant-45.svg 
b/src/js/guadec_map/maki-guadec-svg/restaurant-45.svg
new file mode 100644
index 0000000..c8b5daa
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/restaurant-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="restaurant-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     id="path11774"
+     d="M 12.473538,2.4258347 9.7969828,17.146889 c -0.3918477,2.154628 4.7682832,3.161012 4.6839722,5.35311 
L 13.811816,39.89761 c -0.10278,2.674682 2.676556,2.676555 2.676556,2.676555 0,0 2.779335,-0.0019 
2.676555,-2.676555 L 18.495788,22.499999 c -0.08404,-2.18835 4.639542,-3.160475 4.683972,-5.35311 L 
20.503205,2.4258347 H 19.164927 L 19.834066,13.132056 17.826649,14.470334 17.157511,2.4258347 H 15.819233 L 
15.150094,14.470334 13.142677,13.132056 13.811816,2.4258347 Z m 22.750722,0 c -1.971016,0 -5.25729,1.7528762 
-6.571211,4.3807183 -1.094979,1.9710155 -1.458455,6.374217 -1.458455,9.002059 v 6.691387 c 0,2.189958 
2.919854,2.676556 4.014833,2.676556 L 29.871149,39.89761 c -0.242228,2.665581 2.676555,2.676555 
2.676555,2.676555 0,0 2.676556,0 2.676556,-2.676555 z"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:2.6765554" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/rocket-45.svg b/src/js/guadec_map/maki-guadec-svg/rocket-45.svg
new file mode 100644
index 0000000..b18fc28
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/rocket-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="rocket-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     id="path7143"
+     inkscape:connector-curvature="0"
+     d="m 38.162868,3.1437063 c -6.717829,0 -15.731955,4.4183056 -21.785236,12.0144277 h -5.018083 c 
-3.6260162,0 -5.704247,2.594515 -7.135165,5.33831 l -1.9156195,3.672509 h 4.5224157 4.5283688 l 
4.699753,4.505412 4.699753,4.505411 v 4.341113 4.335405 l 3.830925,-1.836105 c 2.86215,-1.372048 
5.56858,-3.36434 5.56858,-6.840413 V 28.369198 C 38.082345,22.566228 42.691235,13.924853 42.691235,7.4848191 
V 3.1437063 Z M 30.15856,12.154527 c 1.730451,0 3.133169,1.344715 3.133169,3.003607 v 0 c 0,1.658892 
-1.402718,3.003606 -3.133169,3.003606 v 0 c -1.730449,0 -3.133167,-1.344714 -3.133167,-3.003606 v 0 c 
0,-1.658892 1.402718,-3.003607 3.133167,-3.003607 z M 9.7929645,30.176168 8.2263803,31.67797 c 
-2.2627744,2.169208 -3.1331688,7.509018 -3.1331688,7.509018 0,0 5.3201205,-0.594715 7.8329215,-3.003607 l 
1.566585,-1.501803 z"
+     style="stroke-width:3.06770396;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/star-11.svg b/src/js/guadec_map/maki-guadec-svg/star-11.svg
new file mode 100644
index 0000000..858111b
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/star-11.svg
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd";>
+<svg version="1.1"
+        id="svg4764" inkscape:version="0.91 r13725" sodipodi:docname="star-11.svg" 
xmlns:cc="http://creativecommons.org/ns#"; xmlns:dc="http://purl.org/dc/elements/1.1/"; 
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"; 
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"; 
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"; xmlns:svg="http://www.w3.org/2000/svg";
+        xmlns="http://www.w3.org/2000/svg"; xmlns:xlink="http://www.w3.org/1999/xlink"; x="0px" y="0px" 
width="11px" height="11px"
+        viewBox="0 0 11 11" style="enable-background:new 0 0 11 11;" xml:space="preserve">
+<path id="path4749-2-8-2" inkscape:connector-curvature="0" sodipodi:nodetypes="ccccccccccc" 
d="M5.4,0L4,3.5H0l3,3L1.5,11l3.9-2.6
+       L9.5,11L8,6.5l3-3H7L5.4,0z"/>
+</svg>
diff --git a/src/js/guadec_map/maki-guadec-svg/star-45.svg b/src/js/guadec_map/maki-guadec-svg/star-45.svg
new file mode 100644
index 0000000..47765e5
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/star-45.svg
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="star-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     id="path4749-2-8-2"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccc"
+     d="M 22.122811,1.7546386 16.842174,14.956232 H 1.7546386 L 13.07029,26.271884 7.4124645,43.245361 
22.122811,33.438463 37.587535,43.245361 31.929709,26.271884 43.245361,14.956232 H 28.157826 Z"
+     style="stroke-width:3.77188396;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/suitcase-45.svg 
b/src/js/guadec_map/maki-guadec-svg/suitcase-45.svg
new file mode 100644
index 0000000..f1bbff7
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/suitcase-45.svg
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="suitcase-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     id="path17"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="csccsccssccssccccccc"
+     d="M 33.10047,13.413883 V 7.3564724 c 0,-3.0287055 -3.028707,-3.0287055 -3.028707,-3.0287055 h -14.993 
c 0,0 -3.343387,0.00454 -3.179233,3.0287055 V 13.413883 H 5.84212 c 0,0 -3.0287055,0 -3.0287055,3.028706 v 
21.200939 c 0,3.028705 3.0287055,3.028705 3.0287055,3.028705 h 33.315761 c 0,0 3.028705,0 3.028705,-3.028705 
V 16.442589 c 0,-3.028706 -3.028705,-3.028706 -3.028705,-3.028706 z M 16.442589,8.8708252 H 28.557411 V 
13.413883 H 16.442589 Z"
+     style="stroke-width:3.0287056;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/theatre-45.svg 
b/src/js/guadec_map/maki-guadec-svg/theatre-45.svg
new file mode 100644
index 0000000..b6ce2b8
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/theatre-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="theatre-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     id="path6342-3"
+     d="m 4.651358,1.4061495 c 0,0 -3.2452078,0 -3.2452078,3.2452078 V 21.390788 c 0,5.615183 
1.1488036,12.467439 11.3582278,12.467439 h 1.622603 v -9.735623 l -8.1130191,3.245207 c 0,0 0,-8.113019 
8.1130191,-8.113019 V 14.38698 c 0,-2.296958 0.281684,-4.286595 1.622604,-5.7615413 1.238047,-1.3616892 
3.260136,-4.0798752 8.619921,-1.5275193 l 2.738307,1.78097 V 4.6513573 c 0,0 0,-3.2452078 
-3.245208,-3.2452078 -2.296958,0 -6.417723,3.2452078 -9.735624,3.2452078 -3.3179,0 -7.1832671,-3.2452078 
-9.735623,-3.2452078 z m 3.2452078,6.4904156 c 1.7923282,0 3.2452082,1.4528795 3.2452082,3.2452069 0,1.792329 
-1.45288,3.245208 -3.2452082,3.245208 -1.7923283,0 -3.2452078,-1.452879 -3.2452078,-3.245208 0,-1.7923274 
1.4528795,-3.2452069 3.2452078,-3.2452069 z M 20.877397,11.141772 c 0,0 -3.245208,0 -3.245208,3.245208 v 
16.226039 c 0,6.490415 3.245208,12.980831 12.98083,12.980831 9.735624,0 12.980831,-6.490416 
12.980831,-12.980831 V 14.38698 c 0,-3.245208 -3.245207,-3.245208 -3.245207,-3.
 245208 -
 2.296958,0 -6.417723,3.245208 -9.735624,3.245208 -3.317899,0 -7.183266,-3.245208 -9.735622,-3.245208 z m 
3.245208,6.490416 c 1.792328,0 3.245208,1.45288 3.245208,3.245208 0,1.792328 -1.45288,3.245208 
-3.245208,3.245208 -1.792329,0 -3.245208,-1.45288 -3.245208,-3.245208 0,-1.792328 1.452879,-3.245208 
3.245208,-3.245208 z m 12.98083,0 c 1.792328,0 3.245208,1.45288 3.245208,3.245208 0,1.792328 
-1.45288,3.245208 -3.245208,3.245208 -1.792328,0 -3.245208,-1.45288 -3.245208,-3.245208 0,-1.792328 
1.45288,-3.245208 3.245208,-3.245208 z M 22.500001,30.613019 h 8.113018 8.11302 c 0,0 0,8.113019 
-8.11302,8.113019 -8.113018,0 -8.113018,-8.113019 -8.113018,-8.113019 z"
+     style="fill:#4a86cf;fill-opacity:1;stroke-width:3.24520779" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/town-hall-45.svg 
b/src/js/guadec_map/maki-guadec-svg/town-hall-45.svg
new file mode 100644
index 0000000..f5df5ba
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/town-hall-45.svg
@@ -0,0 +1,51 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.0"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   id="svg1360"
+   xml:space="preserve"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="town-hall-45.svg"><metadata
+     id="metadata19"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><sodipodi:namedview
+     inkscape:window-height="702"
+     inkscape:window-width="1444"
+     inkscape:pageshadow="2"
+     inkscape:pageopacity="0.0"
+     guidetolerance="10.0"
+     gridtolerance="10.0"
+     objecttolerance="10.0"
+     borderopacity="1.0"
+     bordercolor="#666666"
+     pagecolor="#ffffff"
+     id="base"
+     inkscape:zoom="7.6744655"
+     inkscape:cx="-10.029193"
+     inkscape:cy="10.940374"
+     inkscape:window-x="171"
+     inkscape:window-y="339"
+     inkscape:current-layer="svg1360"
+     showgrid="false"
+     inkscape:window-maximized="0"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0" /><defs
+     id="defs1391" /><path
+     inkscape:connector-curvature="0"
+     id="path7509"
+     d="M 22.500001,1.5364508 1.5364522,12.648099 v 1.788997 H 43.463548 V 12.648099 Z M 4.7616135,17.662257 
v 16.125808 l -3.2251613,5.014158 v 4.661326 H 43.463548 V 38.802223 L 40.238387,33.788065 V 17.662257 Z m 
6.4503225,3.225161 h 3.225162 v 17.738389 h -3.225162 z m 9.675484,0 h 3.225162 V 38.625807 H 20.88742 Z m 
9.675483,0 h 3.225161 v 17.738389 h -3.225161 z"
+     style="stroke-width:3.22516131;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/maki-guadec-svg/village-45.svg 
b/src/js/guadec_map/maki-guadec-svg/village-45.svg
new file mode 100644
index 0000000..dbbdd08
--- /dev/null
+++ b/src/js/guadec_map/maki-guadec-svg/village-45.svg
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 19.2.1, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/";
+   xmlns:cc="http://creativecommons.org/ns#";
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#";
+   xmlns:svg="http://www.w3.org/2000/svg";
+   xmlns="http://www.w3.org/2000/svg";
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd";
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape";
+   version="1.1"
+   id="svg4619"
+   inkscape:version="0.92.2 (5c3e80d, 2017-08-06)"
+   sodipodi:docname="village-45.svg"
+   x="0px"
+   y="0px"
+   width="45"
+   height="45"
+   viewBox="0 0 45 45"
+   xml:space="preserve"><metadata
+     id="metadata8"><rdf:RDF><cc:Work
+         rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage"; 
/><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+     id="defs6" /><sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1916"
+     inkscape:window-height="1153"
+     id="namedview4"
+     showgrid="false"
+     inkscape:zoom="5.6686394"
+     inkscape:cx="-29.87399"
+     inkscape:cy="14.663949"
+     inkscape:window-x="0"
+     inkscape:window-y="45"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg4619" /><path
+     inkscape:connector-curvature="0"
+     d="m 19.210366,11.00715 a 0.81851023,0.81851023 0 0 0 -1.157091,0 L 3.5896413,25.470784 a 
0.82179742,0.82179742 0 0 0 0.5785454,1.393769 h 4.6020656 v 15.617438 a 0.81851023,0.81851023 0 0 0 
0.8185102,0.81851 H 21.093926 a 0.81851023,0.81851023 0 0 0 0.825084,-0.811936 v 0 -17.84944 a 
0.81851023,0.81851023 0 0 1 0.239965,-0.578545 l 4.690821,-5.414002 z m -0.578545,25.718972 h -3.28719 v 
-3.28719 h 3.28719 z m 0,-6.57438 h -3.28719 v -3.287189 h 3.28719 z M 40.820352,17.002984 h -1.643595 a 
0.82179742,0.82179742 0 0 0 -0.821797,0.821797 v 5.752582 l -4.352239,-5.995834 a 0.81851023,0.81851023 0 0 0 
-1.157091,0 l -7.455346,9.059495 a 0.80864866,0.80864866 0 0 0 -0.184083,0.512801 v 15.318304 a 
0.81851023,0.81851023 0 0 0 0.808649,0.828372 h 4.930784 a 0.83165899,0.83165899 0 0 0 0.834946,-0.828372 v 0 
-5.746007 h 3.28719 v 5.74272 a 0.83165899,0.83165899 0 0 0 0.831659,0.831659 h 4.930785 a 
0.82179742,0.82179742 0 0 0 0.811935,-0.81851 V 17.824781 A 0.82179742,0.82179742
  0 0 0 4
 0.820352,17.002984 Z M 31.78058,33.438932 h -3.287189 v -3.28719 h 3.287189 z m 6.57438,0 h -3.28719 v 
-3.28719 h 3.28719 z"
+     id="path4"
+     style="stroke-width:3.28718972;fill:#4a86cf;fill-opacity:1" /></svg>
\ No newline at end of file
diff --git a/src/js/guadec_map/sprite.json b/src/js/guadec_map/sprite.json
new file mode 100644
index 0000000..ab4a54e
--- /dev/null
+++ b/src/js/guadec_map/sprite.json
@@ -0,0 +1,191 @@
+{
+  "airport-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 0,
+    "y": 0
+  },
+  "bank-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 45,
+    "y": 0
+  },
+  "bar-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 0,
+    "y": 45
+  },
+  "bus-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 45,
+    "y": 45
+  },
+  "cafe-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 90,
+    "y": 0
+  },
+  "circle-11": {
+    "height": 11,
+    "pixelRatio": 1,
+    "width": 11,
+    "x": 225,
+    "y": 90
+  },
+  "circle-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 135,
+    "y": 0
+  },
+  "gnome-guadec-blue": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 90,
+    "y": 45
+  },
+  "gnome-guadec-red": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 135,
+    "y": 45
+  },
+  "gnome-guadec-yellow": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 0,
+    "y": 90
+  },
+  "home-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 45,
+    "y": 90
+  },
+  "hospital-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 90,
+    "y": 90
+  },
+  "karaoke-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 135,
+    "y": 90
+  },
+  "lodging-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 0,
+    "y": 135
+  },
+  "marker-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 45,
+    "y": 135
+  },
+  "music-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 90,
+    "y": 135
+  },
+  "park-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 135,
+    "y": 135
+  },
+  "parking-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 180,
+    "y": 0
+  },
+  "rail-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 225,
+    "y": 0
+  },
+  "restaurant-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 270,
+    "y": 0
+  },
+  "rocket-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 315,
+    "y": 0
+  },
+  "star-11": {
+    "height": 11,
+    "pixelRatio": 1,
+    "width": 11,
+    "x": 236,
+    "y": 90
+  },
+  "star-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 180,
+    "y": 45
+  },
+  "suitcase-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 225,
+    "y": 45
+  },
+  "theatre-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 270,
+    "y": 45
+  },
+  "town-hall-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 315,
+    "y": 45
+  },
+  "village-45": {
+    "height": 45,
+    "pixelRatio": 1,
+    "width": 45,
+    "x": 180,
+    "y": 90
+  }
+}
\ No newline at end of file
diff --git a/src/js/guadec_map/sprite.png b/src/js/guadec_map/sprite.png
new file mode 100644
index 0000000..0efc1ae
Binary files /dev/null and b/src/js/guadec_map/sprite.png differ
diff --git a/src/js/guadec_map/sprite 2x json b/src/js/guadec_map/sprite 2x json
new file mode 100644
index 0000000..8c8b10a
--- /dev/null
+++ b/src/js/guadec_map/sprite 2x json
@@ -0,0 +1,191 @@
+{
+  "airport-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 0,
+    "y": 0
+  },
+  "bank-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 90,
+    "y": 0
+  },
+  "bar-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 0,
+    "y": 90
+  },
+  "bus-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 90,
+    "y": 90
+  },
+  "cafe-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 180,
+    "y": 0
+  },
+  "circle-11": {
+    "height": 22,
+    "pixelRatio": 2,
+    "width": 22,
+    "x": 450,
+    "y": 180
+  },
+  "circle-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 270,
+    "y": 0
+  },
+  "gnome-guadec-blue": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 180,
+    "y": 90
+  },
+  "gnome-guadec-red": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 270,
+    "y": 90
+  },
+  "gnome-guadec-yellow": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 0,
+    "y": 180
+  },
+  "home-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 90,
+    "y": 180
+  },
+  "hospital-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 180,
+    "y": 180
+  },
+  "karaoke-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 270,
+    "y": 180
+  },
+  "lodging-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 0,
+    "y": 270
+  },
+  "marker-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 90,
+    "y": 270
+  },
+  "music-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 180,
+    "y": 270
+  },
+  "park-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 270,
+    "y": 270
+  },
+  "parking-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 360,
+    "y": 0
+  },
+  "rail-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 450,
+    "y": 0
+  },
+  "restaurant-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 540,
+    "y": 0
+  },
+  "rocket-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 630,
+    "y": 0
+  },
+  "star-11": {
+    "height": 22,
+    "pixelRatio": 2,
+    "width": 22,
+    "x": 472,
+    "y": 180
+  },
+  "star-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 360,
+    "y": 90
+  },
+  "suitcase-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 450,
+    "y": 90
+  },
+  "theatre-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 540,
+    "y": 90
+  },
+  "town-hall-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 630,
+    "y": 90
+  },
+  "village-45": {
+    "height": 90,
+    "pixelRatio": 2,
+    "width": 90,
+    "x": 360,
+    "y": 180
+  }
+}
\ No newline at end of file
diff --git a/src/js/guadec_map/sprite 2x png b/src/js/guadec_map/sprite 2x png
new file mode 100644
index 0000000..38259c6
Binary files /dev/null and b/src/js/guadec_map/sprite 2x png differ
diff --git a/src/js/main.js b/src/js/main.js
new file mode 100644
index 0000000..c83f282
--- /dev/null
+++ b/src/js/main.js
@@ -0,0 +1,181 @@
+/*
+Main Javascript file
+
+Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+
+Permission is hereby granted, free of charge, to any person obtaining a copy of
+this software and associated documentation files (the "Software"), to deal in
+the Software without restriction, including without limitation the rights to
+use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+of the Software, and to permit persons to whom the Software is furnished to do
+so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+var DEBUG = 1;
+var GOOGLE_ANALYTICS_ID = 'UA-00000000-1';
+
+(function($) {
+
+  $.fn.cookiesMessage = function(options) {
+
+    return this.each(function() {
+      var elem = $(this);
+
+      var settings = {
+        cookieName: 'cookiesaccepted',
+        legalURL: '/legal/',
+        declineURL: 'about:blank',
+        acceptSelector: '.accept',
+        declineSelector: '.decline',
+        acceptCallback: acceptCallback,
+        declineCallback: declineCallback,
+        hideOnAccept: true,
+        hideOnDecline: false
+      };
+
+      $.extend(settings, options);
+
+      // Connect signals
+      function hasCookie() {
+        return (new RegExp("(?:^|;\\s*)" + encodeURIComponent(settings.cookieName).replace(/[\-\.\+\*]/g, 
"\\$&") + "\\s*\\=")).test(document.cookie);
+      }
+
+      function setCookie() {
+        document.cookie = encodeURIComponent(settings.cookieName) + "=" + encodeURIComponent(1) + "; path=/";
+      }
+
+      function acceptClicked() {
+        DEBUG > 0 && console.log('Accept cookies clicked')
+        setCookie();
+        if (settings.hideOnAccept) elem.hide();
+        if (typeof(settings.acceptCallback) === 'function') settings.acceptCallback(elem);
+      }
+
+      function declineClicked() {
+        DEBUG > 0 && console.log('Decline cookies clicked')
+        if (settings.hideOnDecline) elem.hide();
+        if (typeof(settings.declineCallback) === 'function') settings.declineCallback(elem);
+      }
+
+      function acceptCallback(elem) {
+        DEBUG > 0 && console.log('Accepted cookies');
+      }
+
+      function declineCallback(elem) {
+        window.location = settings.declineURL;
+      }
+
+      elem.find(settings.acceptSelector).click(acceptClicked);
+      elem.find(settings.declineSelector).click(declineClicked);
+
+      if (!hasCookie()) {
+        elem.show();
+      } else {
+        elem.hide();
+        google_analytics();
+      }
+    });
+  };
+
+  $.qroverlay = function(url, size, delay, alpha, styles) {
+    size = size || 240;
+    delay = delay || 200;
+    alpha = alpha || 0.8;
+    styles = {
+      position: 'fixed',
+      display: 'block',
+      top: '50%',
+      left: '50%',
+      width: 0,
+      height: 0,
+      backgroundImage: 'url(http://chart.apis.google.com/chart?cht=qr&chs=' + size + 'x' + size + '&chl=' + 
url + ')',
+      backgroundColor: 'rgba(0,0,0,' + alpha + ')',
+      backgroundPosition: 'center center',
+      backgroundRepeat: 'no-repeat',
+      zIndex: 100000
+    }
+    $('<div></div>').css(styles).appendTo('body').click(function(){
+      $(this.remove());
+    }).animate({left:0, top:0, width: $(document).width(), height: $(window).height()},delay);
+  };
+}(jQuery));
+
+$('[data-toggle="offcanvas"]').click(function () {
+  var target = $($('[data-toggle="offcanvas"]').attr('data-target'));
+  if (target.hasClass('inactive')) {
+    target.removeClass('inactive');
+    target.addClass('active');
+  } else if (target.hasClass('active')) {
+    target.removeClass('active');
+    target.addClass('inactive');
+  } else {
+    target.addClass('active');
+  }
+  return false;
+});
+
+function scrollTo(elemid,margin) {
+       elemid = elemid || 'body';
+       margin = margin || 0;
+       $('html,body').animate({ scrollTop: $(elemid).offset().top - margin }, 'slow');
+}
+
+function showMorePosts(elem) {
+  var page = $(elem).attr('data-page');
+  $.get('./?page=' + page, function(data) {
+    if (data) {
+      $('#postlist').append(data);
+      $(elem).attr('data-page', page + 1);
+    } else {
+      $('#showmorerow').remove();
+    }
+  }, 'json');
+}
+
+function google_analytics() {
+  (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_ID, 'auto');
+  ga('send', 'pageview');
+}
+
+$(document).ready(function(){
+  // Cookies message
+  // $('#cookiesmessage').cookiesMessage({
+  //   acceptCallback: google_analytics
+  // });
+
+  // QR Codes
+  $('.qrcode').click(function(){
+    var url = $(this).attr('data-url');
+    $.qroverlay(url);
+    return false;
+  });
+
+  // Toggle go up button
+  $(document).scroll(function(){
+    if ($(document).scrollTop() > 200) {
+      $('#goup').show();
+    } else {
+      $('#goup').hide();
+    }
+  });
+
+  // Go up button
+  $('#goup').click(function(){
+    scrollTo('#header');
+  });
+});
diff --git a/src/sass/compass-sass-base/_animations.sass b/src/sass/compass-sass-base/_animations.sass
new file mode 100644
index 0000000..1b99b4e
--- /dev/null
+++ b/src/sass/compass-sass-base/_animations.sass
@@ -0,0 +1,196 @@
+// Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+// Base animation settings
+@mixin animation-base
+    animation-duration: 0.3s
+    -webkit-animation-duration: 0.3s
+    animation-timing-function: ease-in-out
+    -webkit-animation-timing-function: ease-in-out
+
+// Infinite animation loop
+@mixin animation-infinite-1s
+    animation-duration: 1s
+    -webkit-animation-duration: 1s
+    animation-timing-function: linear
+    -webkit-animation-timing-function: linear
+    animation-iteration-count: infinite
+    -webkit-animation-iteration-count: infinite
+
+// Fade in animation
+@mixin animation-fadein
+    @include animation-base
+    animation-name: fadein
+    -webkit-animation-name: fadein
+
+@keyframes fadein
+    0%
+        opacity: 0
+    100%
+        opacity: 1
+
+@-webkit-keyframes fadein
+    0%
+        opacity: 0
+    100%
+        opacity: 1
+
+
+// Fade out animation
+@mixin animation-fadeout
+    @include animation-base
+    animation-name: fadeout
+    -webkit-animation-name: fadeout
+
+@keyframes fadeout
+    0%
+        opacity: 1
+    100%
+        opacity: 0
+
+@-webkit-keyframes fadeout
+    0%
+        opacity: 1
+    100%
+        opacity: 0
+
+
+// Zoom in animation
+@mixin animation-zoomin
+    @include animation-base
+    animation-name: zoomin
+    -webkit-animation-name: zoomin
+
+@keyframes zoomin
+    0%
+        transform: scale(0)
+        opacity: 0
+    100%
+        transform: scale(1.0)
+        opacity: 1
+
+@-webkit-keyframes zoomin
+    0%
+        transform: scale(0)
+        opacity: 0.2
+    100%
+        transform: scale(1.0)
+        opacity: 1
+
+
+// Slide up animation
+@mixin animation-slideup
+    @include animation-base
+    animation-name: slideup
+    -webkit-animation-name: slideup
+
+@keyframes slideup
+    0%
+        transform: translateY(0%)
+    100%
+        transform: translateY(-100%)
+
+@-webkit-keyframes slideup
+    0%
+        transform: translateY(0%)
+    100%
+        transform: translateY(-100%)
+
+
+// Slide down animation
+@mixin animation-slidedown
+    @include animation-base
+    animation-name: slidedown
+    -webkit-animation-name: slidedown
+
+@keyframes slidedown
+    0%
+        transform: translateY(-100%)
+    100%
+        transform: translateY(0%)
+
+@-webkit-keyframes slidedown
+    0%
+        transform: translateY(-100%)
+    100%
+        transform: translateY(0%)
+
+
+// Slide right animation
+@mixin animation-slideright
+    @include animation-base
+    animation-name: slideright
+    -webkit-animation-name: slideright
+
+@keyframes slideright
+    0%
+        transform: translateX(-100%)
+    100%
+        transform: translateX(0%)
+
+@-webkit-keyframes slideright
+    0%
+        transform: translateX(-100%)
+    100%
+        transform: translateX(0%)
+
+
+// Slide right animation
+@mixin animation-slideleft
+    @include animation-base
+    animation-name: slideleft
+    -webkit-animation-name: slideleft
+
+@keyframes slideleft
+    0%
+        transform: translateX(0%)
+    100%
+        transform: translateX(-100%)
+
+@-webkit-keyframes slideleft
+    0%
+        transform: translateX(0%)
+    100%
+        transform: translateX(-100%)
+
+
+// Slide right animation
+@mixin animation-background_sweep
+    @include animation-infinite-1s
+    animation-name: background_sweep
+    -webkit-animation-name: background_sweep
+
+@keyframes background_sweep
+    0%
+        background-position: 100% 0
+    100%
+        background-position: 0 0
+
+@-webkit-keyframes background_sweep
+    0%
+        background-position: 100% 0
+    100%
+        background-position: 0 0
+
+.animation_loader
+    background: #dde3e8
+    background: linear-gradient(90deg, #f0f4f7 35%, #dde3e8 50%, #f0f4f7 65%)
+    background-size: 300% 100%
+    @include animation-background_sweep
diff --git a/src/sass/compass-sass-base/_base.sass b/src/sass/compass-sass-base/_base.sass
new file mode 100644
index 0000000..2e35682
--- /dev/null
+++ b/src/sass/compass-sass-base/_base.sass
@@ -0,0 +1,143 @@
+// Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+
+// Compass imports
+@import "compass/utilities/sprites"
+
+// Fonts
+@font-face
+       font-family: "Source Sans Pro"
+       src: url("../fonts/SourceSansPro-Regular.otf")
+
+@font-face
+       font-family: "Cantarell"
+       src: url("../fonts/cantarell-bold.woff2") format("woff2"), url("../fonts/cantarell-bold.woff") 
format("woff")
+
+// Base colors
+$headerbg: #fff !default
+$highlightbg: #9cd !default
+$mainbg: #357 !default
+$footerbg: #034 !default
+
+// Color calculation parameters
+$min_lightness: 60 !default
+$lighten_percent: 30% !default
+
+// Initial precalculated values
+$footerfg: #ccc !default
+$footerhover: white !default
+
+$headerfg: #ccc !default
+$headerhover: white !default
+
+$mainfg: #ccc !default
+$mainhover: white !default
+
+$highlightselectedbg: lighten($highlightbg, $lighten_percent) !default
+$highlightselectedfg: #ccc !default
+$highlightfg: #ccc !default
+$highlighthover: white !default
+
+$headerselectedbg: lighten($headerbg, $lighten_percent) !default
+$headerselectedfg: #ccc !default
+$headerselectedhover: white !default
+
+$mainselectedbg: lighten($mainbg, $lighten_percent) !default
+$mainselectedfg: #ccc !default
+$mainselectedhover: white !default
+
+$footerselectedbg: lighten($footerbg, $lighten_percent) !default
+$footerselectedfg: #ccc !default
+$footerselectedhover: white !default
+
+// Calculate header colors
+@if lightness($headerbg) < $min_lightness
+       $headerfg: #ccc !default
+       $headerhover: white !default
+@else
+       $headerfg: black !default
+       $headerhover: #333 !default
+
+// Calculate main colors
+@if lightness($mainbg) < $min_lightness
+       $mainfg: #ccc !default
+       $mainhover: white !default
+@else
+       $mainfg: black !default
+       $mainhover: #333 !default
+
+// Calculate highlight colors
+@if lightness($highlightbg) < $min_lightness
+       $highlightfg: #ccc !default
+       $highlighthover: white !default
+@else
+       $highlightfg: black !default
+       $highlighthover: #333 !default
+
+// Calculate selected colors
+@if lightness($headerselectedbg) < $min_lightness
+       $headerselectedfg: #ccc !default
+       $headerselectedhover: white !default
+@else
+       $headerselectedfg: black !default
+       $headerselectedhover: #333 !default
+
+// Calculate footer colors
+@if lightness($footerbg) < $min_lightness
+       $footerfg: #ccc !default
+       $footerhover: white !default
+@else
+       $footerfg: black !default
+       $footerhover: #333 !default
+
+// Calculate selected colors
+@if lightness($footerselectedbg) < $min_lightness
+       $footerselectedfg: #ccc !default
+       $footerselectedhover: white !default
+@else
+       $footerselectedfg: black !default
+       $footerselectedhover: #333 !default
+
+// Color classes for foreground
+.header-color
+       color: $headerbg
+
+.highlight-color
+       color: $highlightbg
+
+.main-color
+       color: $mainbg
+
+.footer-color
+       color: $footerbg
+
+// Background color classes
+.headerbg-color
+       background-color: $headerbg
+
+.highlightbg-color
+       background-color: $highlightbg
+
+.mainbg-color
+       background-color: $mainbg
+
+.footerbg-color
+       background-color: $footerbg
diff --git a/src/sass/compass-sass-base/_bootstrap.scss b/src/sass/compass-sass-base/_bootstrap.scss
new file mode 100644
index 0000000..d598a67
--- /dev/null
+++ b/src/sass/compass-sass-base/_bootstrap.scss
@@ -0,0 +1,8374 @@
+/*!
+ * Bootstrap v4.0.0-beta.2 (https://getbootstrap.com)
+ * Copyright 2011-2017 The Bootstrap Authors
+ * Copyright 2011-2017 Twitter, Inc.
+ * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
+ */
+:root {
+  --blue: #007bff;
+  --indigo: #6610f2;
+  --purple: #6f42c1;
+  --pink: #e83e8c;
+  --red: #dc3545;
+  --orange: #fd7e14;
+  --yellow: #ffc107;
+  --green: #28a745;
+  --teal: #20c997;
+  --cyan: #17a2b8;
+  --white: #fff;
+  --gray: #868e96;
+  --gray-dark: #343a40;
+  --primary: #007bff;
+  --secondary: #868e96;
+  --success: #28a745;
+  --info: #17a2b8;
+  --warning: #ffc107;
+  --danger: #dc3545;
+  --light: #f8f9fa;
+  --dark: #343a40;
+  --breakpoint-xs: 0;
+  --breakpoint-sm: 576px;
+  --breakpoint-md: 768px;
+  --breakpoint-lg: 992px;
+  --breakpoint-xl: 1200px;
+  --font-family-sans-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, 
sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  --font-family-monospace: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", 
monospace;
+}
+
+@media print {
+  *,
+  *::before,
+  *::after {
+    text-shadow: none !important;
+    box-shadow: none !important;
+  }
+  a,
+  a:visited {
+    text-decoration: underline;
+  }
+  abbr[title]::after {
+    content: " (" attr(title) ")";
+  }
+  pre {
+    white-space: pre-wrap !important;
+  }
+  pre,
+  blockquote {
+    border: 1px solid #999;
+    page-break-inside: avoid;
+  }
+  thead {
+    display: table-header-group;
+  }
+  tr,
+  img {
+    page-break-inside: avoid;
+  }
+  p,
+  h2,
+  h3 {
+    orphans: 3;
+    widows: 3;
+  }
+  h2,
+  h3 {
+    page-break-after: avoid;
+  }
+  .navbar {
+    display: none;
+  }
+  .badge {
+    border: 1px solid #000;
+  }
+  .table {
+    border-collapse: collapse !important;
+  }
+  .table td,
+  .table th {
+    background-color: #fff !important;
+  }
+  .table-bordered th,
+  .table-bordered td {
+    border: 1px solid #ddd !important;
+  }
+}
+
+*,
+*::before,
+*::after {
+  box-sizing: border-box;
+}
+
+html {
+  font-family: sans-serif;
+  line-height: 1.15;
+  -webkit-text-size-adjust: 100%;
+  -ms-text-size-adjust: 100%;
+  -ms-overflow-style: scrollbar;
+  -webkit-tap-highlight-color: transparent;
+}
+
+@-ms-viewport {
+  width: device-width;
+}
+
+article, aside, dialog, figcaption, figure, footer, header, hgroup, main, nav, section {
+  display: block;
+}
+
+body {
+  margin: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, 
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1.5;
+  color: #212529;
+  text-align: left;
+  background-color: #fff;
+}
+
+[tabindex="-1"]:focus {
+  outline: none !important;
+}
+
+hr {
+  box-sizing: content-box;
+  height: 0;
+  overflow: visible;
+}
+
+h1, h2, h3, h4, h5, h6 {
+  margin-top: 0;
+  margin-bottom: 0.5rem;
+}
+
+p {
+  margin-top: 0;
+  margin-bottom: 1rem;
+}
+
+abbr[title],
+abbr[data-original-title] {
+  text-decoration: underline;
+  -webkit-text-decoration: underline dotted;
+          text-decoration: underline dotted;
+  cursor: help;
+  border-bottom: 0;
+}
+
+address {
+  margin-bottom: 1rem;
+  font-style: normal;
+  line-height: inherit;
+}
+
+ol,
+ul,
+dl {
+  margin-top: 0;
+  margin-bottom: 1rem;
+}
+
+ol ol,
+ul ul,
+ol ul,
+ul ol {
+  margin-bottom: 0;
+}
+
+dt {
+  font-weight: 700;
+}
+
+dd {
+  margin-bottom: .5rem;
+  margin-left: 0;
+}
+
+blockquote {
+  margin: 0 0 1rem;
+}
+
+dfn {
+  font-style: italic;
+}
+
+b,
+strong {
+  font-weight: bolder;
+}
+
+small {
+  font-size: 80%;
+}
+
+sub,
+sup {
+  position: relative;
+  font-size: 75%;
+  line-height: 0;
+  vertical-align: baseline;
+}
+
+sub {
+  bottom: -.25em;
+}
+
+sup {
+  top: -.5em;
+}
+
+a {
+  color: #007bff;
+  text-decoration: none;
+  background-color: transparent;
+  -webkit-text-decoration-skip: objects;
+}
+
+a:hover {
+  color: #0056b3;
+  text-decoration: underline;
+}
+
+a:not([href]):not([tabindex]) {
+  color: inherit;
+  text-decoration: none;
+}
+
+a:not([href]):not([tabindex]):focus, a:not([href]):not([tabindex]):hover {
+  color: inherit;
+  text-decoration: none;
+}
+
+a:not([href]):not([tabindex]):focus {
+  outline: 0;
+}
+
+pre,
+code,
+kbd,
+samp {
+  font-family: monospace, monospace;
+  font-size: 1em;
+}
+
+pre {
+  margin-top: 0;
+  margin-bottom: 1rem;
+  overflow: auto;
+  -ms-overflow-style: scrollbar;
+}
+
+figure {
+  margin: 0 0 1rem;
+}
+
+img {
+  vertical-align: middle;
+  border-style: none;
+}
+
+svg:not(:root) {
+  overflow: hidden;
+}
+
+a,
+area,
+button,
+[role="button"],
+input:not([type="range"]),
+label,
+select,
+summary,
+textarea {
+  -ms-touch-action: manipulation;
+      touch-action: manipulation;
+}
+
+table {
+  border-collapse: collapse;
+}
+
+caption {
+  padding-top: 0.75rem;
+  padding-bottom: 0.75rem;
+  color: #868e96;
+  text-align: left;
+  caption-side: bottom;
+}
+
+th {
+  text-align: inherit;
+}
+
+label {
+  display: inline-block;
+  margin-bottom: .5rem;
+}
+
+button {
+  border-radius: 0;
+}
+
+button:focus {
+  outline: 1px dotted;
+  outline: 5px auto -webkit-focus-ring-color;
+}
+
+input,
+button,
+select,
+optgroup,
+textarea {
+  margin: 0;
+  font-family: inherit;
+  font-size: inherit;
+  line-height: inherit;
+}
+
+button,
+input {
+  overflow: visible;
+}
+
+button,
+select {
+  text-transform: none;
+}
+
+button,
+html [type="button"],
+[type="reset"],
+[type="submit"] {
+  -webkit-appearance: button;
+}
+
+button::-moz-focus-inner,
+[type="button"]::-moz-focus-inner,
+[type="reset"]::-moz-focus-inner,
+[type="submit"]::-moz-focus-inner {
+  padding: 0;
+  border-style: none;
+}
+
+input[type="radio"],
+input[type="checkbox"] {
+  box-sizing: border-box;
+  padding: 0;
+}
+
+input[type="date"],
+input[type="time"],
+input[type="datetime-local"],
+input[type="month"] {
+  -webkit-appearance: listbox;
+}
+
+textarea {
+  overflow: auto;
+  resize: vertical;
+}
+
+fieldset {
+  min-width: 0;
+  padding: 0;
+  margin: 0;
+  border: 0;
+}
+
+legend {
+  display: block;
+  width: 100%;
+  max-width: 100%;
+  padding: 0;
+  margin-bottom: .5rem;
+  font-size: 1.5rem;
+  line-height: inherit;
+  color: inherit;
+  white-space: normal;
+}
+
+progress {
+  vertical-align: baseline;
+}
+
+[type="number"]::-webkit-inner-spin-button,
+[type="number"]::-webkit-outer-spin-button {
+  height: auto;
+}
+
+[type="search"] {
+  outline-offset: -2px;
+  -webkit-appearance: none;
+}
+
+[type="search"]::-webkit-search-cancel-button,
+[type="search"]::-webkit-search-decoration {
+  -webkit-appearance: none;
+}
+
+::-webkit-file-upload-button {
+  font: inherit;
+  -webkit-appearance: button;
+}
+
+output {
+  display: inline-block;
+}
+
+summary {
+  display: list-item;
+}
+
+template {
+  display: none;
+}
+
+[hidden] {
+  display: none !important;
+}
+
+h1, h2, h3, h4, h5, h6,
+.h1, .h2, .h3, .h4, .h5, .h6 {
+  margin-bottom: 0.5rem;
+  font-family: inherit;
+  font-weight: 500;
+  line-height: 1.2;
+  color: inherit;
+}
+
+h1, .h1 {
+  font-size: 2.5rem;
+}
+
+h2, .h2 {
+  font-size: 2rem;
+}
+
+h3, .h3 {
+  font-size: 1.75rem;
+}
+
+h4, .h4 {
+  font-size: 1.5rem;
+}
+
+h5, .h5 {
+  font-size: 1.25rem;
+}
+
+h6, .h6 {
+  font-size: 1rem;
+}
+
+.lead {
+  font-size: 1.25rem;
+  font-weight: 300;
+}
+
+.display-1 {
+  font-size: 6rem;
+  font-weight: 300;
+  line-height: 1.2;
+}
+
+.display-2 {
+  font-size: 5.5rem;
+  font-weight: 300;
+  line-height: 1.2;
+}
+
+.display-3 {
+  font-size: 4.5rem;
+  font-weight: 300;
+  line-height: 1.2;
+}
+
+.display-4 {
+  font-size: 3.5rem;
+  font-weight: 300;
+  line-height: 1.2;
+}
+
+hr {
+  margin-top: 1rem;
+  margin-bottom: 1rem;
+  border: 0;
+  border-top: 1px solid rgba(0, 0, 0, 0.1);
+}
+
+small,
+.small {
+  font-size: 80%;
+  font-weight: 400;
+}
+
+mark,
+.mark {
+  padding: 0.2em;
+  background-color: #fcf8e3;
+}
+
+.list-unstyled {
+  padding-left: 0;
+  list-style: none;
+}
+
+.list-inline {
+  padding-left: 0;
+  list-style: none;
+}
+
+.list-inline-item {
+  display: inline-block;
+}
+
+.list-inline-item:not(:last-child) {
+  margin-right: 5px;
+}
+
+.initialism {
+  font-size: 90%;
+  text-transform: uppercase;
+}
+
+.blockquote {
+  margin-bottom: 1rem;
+  font-size: 1.25rem;
+}
+
+.blockquote-footer {
+  display: block;
+  font-size: 80%;
+  color: #868e96;
+}
+
+.blockquote-footer::before {
+  content: "\2014 \00A0";
+}
+
+.img-fluid {
+  max-width: 100%;
+  height: auto;
+}
+
+.img-thumbnail {
+  padding: 0.25rem;
+  background-color: #fff;
+  border: 1px solid #ddd;
+  border-radius: 0.25rem;
+  transition: all 0.2s ease-in-out;
+  max-width: 100%;
+  height: auto;
+}
+
+.figure {
+  display: inline-block;
+}
+
+.figure-img {
+  margin-bottom: 0.5rem;
+  line-height: 1;
+}
+
+.figure-caption {
+  font-size: 90%;
+  color: #868e96;
+}
+
+code,
+kbd,
+pre,
+samp {
+  font-family: "SFMono-Regular", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
+}
+
+code {
+  padding: 0.2rem 0.4rem;
+  font-size: 90%;
+  color: #bd4147;
+  background-color: #f8f9fa;
+  border-radius: 0.25rem;
+}
+
+a > code {
+  padding: 0;
+  color: inherit;
+  background-color: inherit;
+}
+
+kbd {
+  padding: 0.2rem 0.4rem;
+  font-size: 90%;
+  color: #fff;
+  background-color: #212529;
+  border-radius: 0.2rem;
+}
+
+kbd kbd {
+  padding: 0;
+  font-size: 100%;
+  font-weight: 700;
+}
+
+pre {
+  display: block;
+  margin-top: 0;
+  margin-bottom: 1rem;
+  font-size: 90%;
+  color: #212529;
+}
+
+pre code {
+  padding: 0;
+  font-size: inherit;
+  color: inherit;
+  background-color: transparent;
+  border-radius: 0;
+}
+
+.pre-scrollable {
+  max-height: 340px;
+  overflow-y: scroll;
+}
+
+.container {
+  width: 100%;
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-right: auto;
+  margin-left: auto;
+}
+
+@media (min-width: 576px) {
+  .container {
+    max-width: 540px;
+  }
+}
+
+@media (min-width: 768px) {
+  .container {
+    max-width: 720px;
+  }
+}
+
+@media (min-width: 992px) {
+  .container {
+    max-width: 960px;
+  }
+}
+
+@media (min-width: 1200px) {
+  .container {
+    max-width: 1140px;
+  }
+}
+
+.container-fluid {
+  width: 100%;
+  padding-right: 15px;
+  padding-left: 15px;
+  margin-right: auto;
+  margin-left: auto;
+}
+
+.row {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  margin-right: -15px;
+  margin-left: -15px;
+}
+
+.no-gutters {
+  margin-right: 0;
+  margin-left: 0;
+}
+
+.no-gutters > .col,
+.no-gutters > [class*="col-"] {
+  padding-right: 0;
+  padding-left: 0;
+}
+
+.col-1, .col-2, .col-3, .col-4, .col-5, .col-6, .col-7, .col-8, .col-9, .col-10, .col-11, .col-12, .col,
+.col-auto, .col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, 
.col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12, .col-sm,
+.col-sm-auto, .col-md-1, .col-md-2, .col-md-3, .col-md-4, .col-md-5, .col-md-6, .col-md-7, .col-md-8, 
.col-md-9, .col-md-10, .col-md-11, .col-md-12, .col-md,
+.col-md-auto, .col-lg-1, .col-lg-2, .col-lg-3, .col-lg-4, .col-lg-5, .col-lg-6, .col-lg-7, .col-lg-8, 
.col-lg-9, .col-lg-10, .col-lg-11, .col-lg-12, .col-lg,
+.col-lg-auto, .col-xl-1, .col-xl-2, .col-xl-3, .col-xl-4, .col-xl-5, .col-xl-6, .col-xl-7, .col-xl-8, 
.col-xl-9, .col-xl-10, .col-xl-11, .col-xl-12, .col-xl,
+.col-xl-auto {
+  position: relative;
+  width: 100%;
+  min-height: 1px;
+  padding-right: 15px;
+  padding-left: 15px;
+}
+
+.col {
+  -ms-flex-preferred-size: 0;
+      flex-basis: 0;
+  -ms-flex-positive: 1;
+      flex-grow: 1;
+  max-width: 100%;
+}
+
+.col-auto {
+  -ms-flex: 0 0 auto;
+      flex: 0 0 auto;
+  width: auto;
+  max-width: none;
+}
+
+.col-1 {
+  -ms-flex: 0 0 8.333333%;
+      flex: 0 0 8.333333%;
+  max-width: 8.333333%;
+}
+
+.col-2 {
+  -ms-flex: 0 0 16.666667%;
+      flex: 0 0 16.666667%;
+  max-width: 16.666667%;
+}
+
+.col-3 {
+  -ms-flex: 0 0 25%;
+      flex: 0 0 25%;
+  max-width: 25%;
+}
+
+.col-4 {
+  -ms-flex: 0 0 33.333333%;
+      flex: 0 0 33.333333%;
+  max-width: 33.333333%;
+}
+
+.col-5 {
+  -ms-flex: 0 0 41.666667%;
+      flex: 0 0 41.666667%;
+  max-width: 41.666667%;
+}
+
+.col-6 {
+  -ms-flex: 0 0 50%;
+      flex: 0 0 50%;
+  max-width: 50%;
+}
+
+.col-7 {
+  -ms-flex: 0 0 58.333333%;
+      flex: 0 0 58.333333%;
+  max-width: 58.333333%;
+}
+
+.col-8 {
+  -ms-flex: 0 0 66.666667%;
+      flex: 0 0 66.666667%;
+  max-width: 66.666667%;
+}
+
+.col-9 {
+  -ms-flex: 0 0 75%;
+      flex: 0 0 75%;
+  max-width: 75%;
+}
+
+.col-10 {
+  -ms-flex: 0 0 83.333333%;
+      flex: 0 0 83.333333%;
+  max-width: 83.333333%;
+}
+
+.col-11 {
+  -ms-flex: 0 0 91.666667%;
+      flex: 0 0 91.666667%;
+  max-width: 91.666667%;
+}
+
+.col-12 {
+  -ms-flex: 0 0 100%;
+      flex: 0 0 100%;
+  max-width: 100%;
+}
+
+.order-first {
+  -ms-flex-order: -1;
+      order: -1;
+}
+
+.order-1 {
+  -ms-flex-order: 1;
+      order: 1;
+}
+
+.order-2 {
+  -ms-flex-order: 2;
+      order: 2;
+}
+
+.order-3 {
+  -ms-flex-order: 3;
+      order: 3;
+}
+
+.order-4 {
+  -ms-flex-order: 4;
+      order: 4;
+}
+
+.order-5 {
+  -ms-flex-order: 5;
+      order: 5;
+}
+
+.order-6 {
+  -ms-flex-order: 6;
+      order: 6;
+}
+
+.order-7 {
+  -ms-flex-order: 7;
+      order: 7;
+}
+
+.order-8 {
+  -ms-flex-order: 8;
+      order: 8;
+}
+
+.order-9 {
+  -ms-flex-order: 9;
+      order: 9;
+}
+
+.order-10 {
+  -ms-flex-order: 10;
+      order: 10;
+}
+
+.order-11 {
+  -ms-flex-order: 11;
+      order: 11;
+}
+
+.order-12 {
+  -ms-flex-order: 12;
+      order: 12;
+}
+
+.offset-1 {
+  margin-left: 8.333333%;
+}
+
+.offset-2 {
+  margin-left: 16.666667%;
+}
+
+.offset-3 {
+  margin-left: 25%;
+}
+
+.offset-4 {
+  margin-left: 33.333333%;
+}
+
+.offset-5 {
+  margin-left: 41.666667%;
+}
+
+.offset-6 {
+  margin-left: 50%;
+}
+
+.offset-7 {
+  margin-left: 58.333333%;
+}
+
+.offset-8 {
+  margin-left: 66.666667%;
+}
+
+.offset-9 {
+  margin-left: 75%;
+}
+
+.offset-10 {
+  margin-left: 83.333333%;
+}
+
+.offset-11 {
+  margin-left: 91.666667%;
+}
+
+@media (min-width: 576px) {
+  .col-sm {
+    -ms-flex-preferred-size: 0;
+        flex-basis: 0;
+    -ms-flex-positive: 1;
+        flex-grow: 1;
+    max-width: 100%;
+  }
+  .col-sm-auto {
+    -ms-flex: 0 0 auto;
+        flex: 0 0 auto;
+    width: auto;
+    max-width: none;
+  }
+  .col-sm-1 {
+    -ms-flex: 0 0 8.333333%;
+        flex: 0 0 8.333333%;
+    max-width: 8.333333%;
+  }
+  .col-sm-2 {
+    -ms-flex: 0 0 16.666667%;
+        flex: 0 0 16.666667%;
+    max-width: 16.666667%;
+  }
+  .col-sm-3 {
+    -ms-flex: 0 0 25%;
+        flex: 0 0 25%;
+    max-width: 25%;
+  }
+  .col-sm-4 {
+    -ms-flex: 0 0 33.333333%;
+        flex: 0 0 33.333333%;
+    max-width: 33.333333%;
+  }
+  .col-sm-5 {
+    -ms-flex: 0 0 41.666667%;
+        flex: 0 0 41.666667%;
+    max-width: 41.666667%;
+  }
+  .col-sm-6 {
+    -ms-flex: 0 0 50%;
+        flex: 0 0 50%;
+    max-width: 50%;
+  }
+  .col-sm-7 {
+    -ms-flex: 0 0 58.333333%;
+        flex: 0 0 58.333333%;
+    max-width: 58.333333%;
+  }
+  .col-sm-8 {
+    -ms-flex: 0 0 66.666667%;
+        flex: 0 0 66.666667%;
+    max-width: 66.666667%;
+  }
+  .col-sm-9 {
+    -ms-flex: 0 0 75%;
+        flex: 0 0 75%;
+    max-width: 75%;
+  }
+  .col-sm-10 {
+    -ms-flex: 0 0 83.333333%;
+        flex: 0 0 83.333333%;
+    max-width: 83.333333%;
+  }
+  .col-sm-11 {
+    -ms-flex: 0 0 91.666667%;
+        flex: 0 0 91.666667%;
+    max-width: 91.666667%;
+  }
+  .col-sm-12 {
+    -ms-flex: 0 0 100%;
+        flex: 0 0 100%;
+    max-width: 100%;
+  }
+  .order-sm-first {
+    -ms-flex-order: -1;
+        order: -1;
+  }
+  .order-sm-1 {
+    -ms-flex-order: 1;
+        order: 1;
+  }
+  .order-sm-2 {
+    -ms-flex-order: 2;
+        order: 2;
+  }
+  .order-sm-3 {
+    -ms-flex-order: 3;
+        order: 3;
+  }
+  .order-sm-4 {
+    -ms-flex-order: 4;
+        order: 4;
+  }
+  .order-sm-5 {
+    -ms-flex-order: 5;
+        order: 5;
+  }
+  .order-sm-6 {
+    -ms-flex-order: 6;
+        order: 6;
+  }
+  .order-sm-7 {
+    -ms-flex-order: 7;
+        order: 7;
+  }
+  .order-sm-8 {
+    -ms-flex-order: 8;
+        order: 8;
+  }
+  .order-sm-9 {
+    -ms-flex-order: 9;
+        order: 9;
+  }
+  .order-sm-10 {
+    -ms-flex-order: 10;
+        order: 10;
+  }
+  .order-sm-11 {
+    -ms-flex-order: 11;
+        order: 11;
+  }
+  .order-sm-12 {
+    -ms-flex-order: 12;
+        order: 12;
+  }
+  .offset-sm-0 {
+    margin-left: 0;
+  }
+  .offset-sm-1 {
+    margin-left: 8.333333%;
+  }
+  .offset-sm-2 {
+    margin-left: 16.666667%;
+  }
+  .offset-sm-3 {
+    margin-left: 25%;
+  }
+  .offset-sm-4 {
+    margin-left: 33.333333%;
+  }
+  .offset-sm-5 {
+    margin-left: 41.666667%;
+  }
+  .offset-sm-6 {
+    margin-left: 50%;
+  }
+  .offset-sm-7 {
+    margin-left: 58.333333%;
+  }
+  .offset-sm-8 {
+    margin-left: 66.666667%;
+  }
+  .offset-sm-9 {
+    margin-left: 75%;
+  }
+  .offset-sm-10 {
+    margin-left: 83.333333%;
+  }
+  .offset-sm-11 {
+    margin-left: 91.666667%;
+  }
+}
+
+@media (min-width: 768px) {
+  .col-md {
+    -ms-flex-preferred-size: 0;
+        flex-basis: 0;
+    -ms-flex-positive: 1;
+        flex-grow: 1;
+    max-width: 100%;
+  }
+  .col-md-auto {
+    -ms-flex: 0 0 auto;
+        flex: 0 0 auto;
+    width: auto;
+    max-width: none;
+  }
+  .col-md-1 {
+    -ms-flex: 0 0 8.333333%;
+        flex: 0 0 8.333333%;
+    max-width: 8.333333%;
+  }
+  .col-md-2 {
+    -ms-flex: 0 0 16.666667%;
+        flex: 0 0 16.666667%;
+    max-width: 16.666667%;
+  }
+  .col-md-3 {
+    -ms-flex: 0 0 25%;
+        flex: 0 0 25%;
+    max-width: 25%;
+  }
+  .col-md-4 {
+    -ms-flex: 0 0 33.333333%;
+        flex: 0 0 33.333333%;
+    max-width: 33.333333%;
+  }
+  .col-md-5 {
+    -ms-flex: 0 0 41.666667%;
+        flex: 0 0 41.666667%;
+    max-width: 41.666667%;
+  }
+  .col-md-6 {
+    -ms-flex: 0 0 50%;
+        flex: 0 0 50%;
+    max-width: 50%;
+  }
+  .col-md-7 {
+    -ms-flex: 0 0 58.333333%;
+        flex: 0 0 58.333333%;
+    max-width: 58.333333%;
+  }
+  .col-md-8 {
+    -ms-flex: 0 0 66.666667%;
+        flex: 0 0 66.666667%;
+    max-width: 66.666667%;
+  }
+  .col-md-9 {
+    -ms-flex: 0 0 75%;
+        flex: 0 0 75%;
+    max-width: 75%;
+  }
+  .col-md-10 {
+    -ms-flex: 0 0 83.333333%;
+        flex: 0 0 83.333333%;
+    max-width: 83.333333%;
+  }
+  .col-md-11 {
+    -ms-flex: 0 0 91.666667%;
+        flex: 0 0 91.666667%;
+    max-width: 91.666667%;
+  }
+  .col-md-12 {
+    -ms-flex: 0 0 100%;
+        flex: 0 0 100%;
+    max-width: 100%;
+  }
+  .order-md-first {
+    -ms-flex-order: -1;
+        order: -1;
+  }
+  .order-md-1 {
+    -ms-flex-order: 1;
+        order: 1;
+  }
+  .order-md-2 {
+    -ms-flex-order: 2;
+        order: 2;
+  }
+  .order-md-3 {
+    -ms-flex-order: 3;
+        order: 3;
+  }
+  .order-md-4 {
+    -ms-flex-order: 4;
+        order: 4;
+  }
+  .order-md-5 {
+    -ms-flex-order: 5;
+        order: 5;
+  }
+  .order-md-6 {
+    -ms-flex-order: 6;
+        order: 6;
+  }
+  .order-md-7 {
+    -ms-flex-order: 7;
+        order: 7;
+  }
+  .order-md-8 {
+    -ms-flex-order: 8;
+        order: 8;
+  }
+  .order-md-9 {
+    -ms-flex-order: 9;
+        order: 9;
+  }
+  .order-md-10 {
+    -ms-flex-order: 10;
+        order: 10;
+  }
+  .order-md-11 {
+    -ms-flex-order: 11;
+        order: 11;
+  }
+  .order-md-12 {
+    -ms-flex-order: 12;
+        order: 12;
+  }
+  .offset-md-0 {
+    margin-left: 0;
+  }
+  .offset-md-1 {
+    margin-left: 8.333333%;
+  }
+  .offset-md-2 {
+    margin-left: 16.666667%;
+  }
+  .offset-md-3 {
+    margin-left: 25%;
+  }
+  .offset-md-4 {
+    margin-left: 33.333333%;
+  }
+  .offset-md-5 {
+    margin-left: 41.666667%;
+  }
+  .offset-md-6 {
+    margin-left: 50%;
+  }
+  .offset-md-7 {
+    margin-left: 58.333333%;
+  }
+  .offset-md-8 {
+    margin-left: 66.666667%;
+  }
+  .offset-md-9 {
+    margin-left: 75%;
+  }
+  .offset-md-10 {
+    margin-left: 83.333333%;
+  }
+  .offset-md-11 {
+    margin-left: 91.666667%;
+  }
+}
+
+@media (min-width: 992px) {
+  .col-lg {
+    -ms-flex-preferred-size: 0;
+        flex-basis: 0;
+    -ms-flex-positive: 1;
+        flex-grow: 1;
+    max-width: 100%;
+  }
+  .col-lg-auto {
+    -ms-flex: 0 0 auto;
+        flex: 0 0 auto;
+    width: auto;
+    max-width: none;
+  }
+  .col-lg-1 {
+    -ms-flex: 0 0 8.333333%;
+        flex: 0 0 8.333333%;
+    max-width: 8.333333%;
+  }
+  .col-lg-2 {
+    -ms-flex: 0 0 16.666667%;
+        flex: 0 0 16.666667%;
+    max-width: 16.666667%;
+  }
+  .col-lg-3 {
+    -ms-flex: 0 0 25%;
+        flex: 0 0 25%;
+    max-width: 25%;
+  }
+  .col-lg-4 {
+    -ms-flex: 0 0 33.333333%;
+        flex: 0 0 33.333333%;
+    max-width: 33.333333%;
+  }
+  .col-lg-5 {
+    -ms-flex: 0 0 41.666667%;
+        flex: 0 0 41.666667%;
+    max-width: 41.666667%;
+  }
+  .col-lg-6 {
+    -ms-flex: 0 0 50%;
+        flex: 0 0 50%;
+    max-width: 50%;
+  }
+  .col-lg-7 {
+    -ms-flex: 0 0 58.333333%;
+        flex: 0 0 58.333333%;
+    max-width: 58.333333%;
+  }
+  .col-lg-8 {
+    -ms-flex: 0 0 66.666667%;
+        flex: 0 0 66.666667%;
+    max-width: 66.666667%;
+  }
+  .col-lg-9 {
+    -ms-flex: 0 0 75%;
+        flex: 0 0 75%;
+    max-width: 75%;
+  }
+  .col-lg-10 {
+    -ms-flex: 0 0 83.333333%;
+        flex: 0 0 83.333333%;
+    max-width: 83.333333%;
+  }
+  .col-lg-11 {
+    -ms-flex: 0 0 91.666667%;
+        flex: 0 0 91.666667%;
+    max-width: 91.666667%;
+  }
+  .col-lg-12 {
+    -ms-flex: 0 0 100%;
+        flex: 0 0 100%;
+    max-width: 100%;
+  }
+  .order-lg-first {
+    -ms-flex-order: -1;
+        order: -1;
+  }
+  .order-lg-1 {
+    -ms-flex-order: 1;
+        order: 1;
+  }
+  .order-lg-2 {
+    -ms-flex-order: 2;
+        order: 2;
+  }
+  .order-lg-3 {
+    -ms-flex-order: 3;
+        order: 3;
+  }
+  .order-lg-4 {
+    -ms-flex-order: 4;
+        order: 4;
+  }
+  .order-lg-5 {
+    -ms-flex-order: 5;
+        order: 5;
+  }
+  .order-lg-6 {
+    -ms-flex-order: 6;
+        order: 6;
+  }
+  .order-lg-7 {
+    -ms-flex-order: 7;
+        order: 7;
+  }
+  .order-lg-8 {
+    -ms-flex-order: 8;
+        order: 8;
+  }
+  .order-lg-9 {
+    -ms-flex-order: 9;
+        order: 9;
+  }
+  .order-lg-10 {
+    -ms-flex-order: 10;
+        order: 10;
+  }
+  .order-lg-11 {
+    -ms-flex-order: 11;
+        order: 11;
+  }
+  .order-lg-12 {
+    -ms-flex-order: 12;
+        order: 12;
+  }
+  .offset-lg-0 {
+    margin-left: 0;
+  }
+  .offset-lg-1 {
+    margin-left: 8.333333%;
+  }
+  .offset-lg-2 {
+    margin-left: 16.666667%;
+  }
+  .offset-lg-3 {
+    margin-left: 25%;
+  }
+  .offset-lg-4 {
+    margin-left: 33.333333%;
+  }
+  .offset-lg-5 {
+    margin-left: 41.666667%;
+  }
+  .offset-lg-6 {
+    margin-left: 50%;
+  }
+  .offset-lg-7 {
+    margin-left: 58.333333%;
+  }
+  .offset-lg-8 {
+    margin-left: 66.666667%;
+  }
+  .offset-lg-9 {
+    margin-left: 75%;
+  }
+  .offset-lg-10 {
+    margin-left: 83.333333%;
+  }
+  .offset-lg-11 {
+    margin-left: 91.666667%;
+  }
+}
+
+@media (min-width: 1200px) {
+  .col-xl {
+    -ms-flex-preferred-size: 0;
+        flex-basis: 0;
+    -ms-flex-positive: 1;
+        flex-grow: 1;
+    max-width: 100%;
+  }
+  .col-xl-auto {
+    -ms-flex: 0 0 auto;
+        flex: 0 0 auto;
+    width: auto;
+    max-width: none;
+  }
+  .col-xl-1 {
+    -ms-flex: 0 0 8.333333%;
+        flex: 0 0 8.333333%;
+    max-width: 8.333333%;
+  }
+  .col-xl-2 {
+    -ms-flex: 0 0 16.666667%;
+        flex: 0 0 16.666667%;
+    max-width: 16.666667%;
+  }
+  .col-xl-3 {
+    -ms-flex: 0 0 25%;
+        flex: 0 0 25%;
+    max-width: 25%;
+  }
+  .col-xl-4 {
+    -ms-flex: 0 0 33.333333%;
+        flex: 0 0 33.333333%;
+    max-width: 33.333333%;
+  }
+  .col-xl-5 {
+    -ms-flex: 0 0 41.666667%;
+        flex: 0 0 41.666667%;
+    max-width: 41.666667%;
+  }
+  .col-xl-6 {
+    -ms-flex: 0 0 50%;
+        flex: 0 0 50%;
+    max-width: 50%;
+  }
+  .col-xl-7 {
+    -ms-flex: 0 0 58.333333%;
+        flex: 0 0 58.333333%;
+    max-width: 58.333333%;
+  }
+  .col-xl-8 {
+    -ms-flex: 0 0 66.666667%;
+        flex: 0 0 66.666667%;
+    max-width: 66.666667%;
+  }
+  .col-xl-9 {
+    -ms-flex: 0 0 75%;
+        flex: 0 0 75%;
+    max-width: 75%;
+  }
+  .col-xl-10 {
+    -ms-flex: 0 0 83.333333%;
+        flex: 0 0 83.333333%;
+    max-width: 83.333333%;
+  }
+  .col-xl-11 {
+    -ms-flex: 0 0 91.666667%;
+        flex: 0 0 91.666667%;
+    max-width: 91.666667%;
+  }
+  .col-xl-12 {
+    -ms-flex: 0 0 100%;
+        flex: 0 0 100%;
+    max-width: 100%;
+  }
+  .order-xl-first {
+    -ms-flex-order: -1;
+        order: -1;
+  }
+  .order-xl-1 {
+    -ms-flex-order: 1;
+        order: 1;
+  }
+  .order-xl-2 {
+    -ms-flex-order: 2;
+        order: 2;
+  }
+  .order-xl-3 {
+    -ms-flex-order: 3;
+        order: 3;
+  }
+  .order-xl-4 {
+    -ms-flex-order: 4;
+        order: 4;
+  }
+  .order-xl-5 {
+    -ms-flex-order: 5;
+        order: 5;
+  }
+  .order-xl-6 {
+    -ms-flex-order: 6;
+        order: 6;
+  }
+  .order-xl-7 {
+    -ms-flex-order: 7;
+        order: 7;
+  }
+  .order-xl-8 {
+    -ms-flex-order: 8;
+        order: 8;
+  }
+  .order-xl-9 {
+    -ms-flex-order: 9;
+        order: 9;
+  }
+  .order-xl-10 {
+    -ms-flex-order: 10;
+        order: 10;
+  }
+  .order-xl-11 {
+    -ms-flex-order: 11;
+        order: 11;
+  }
+  .order-xl-12 {
+    -ms-flex-order: 12;
+        order: 12;
+  }
+  .offset-xl-0 {
+    margin-left: 0;
+  }
+  .offset-xl-1 {
+    margin-left: 8.333333%;
+  }
+  .offset-xl-2 {
+    margin-left: 16.666667%;
+  }
+  .offset-xl-3 {
+    margin-left: 25%;
+  }
+  .offset-xl-4 {
+    margin-left: 33.333333%;
+  }
+  .offset-xl-5 {
+    margin-left: 41.666667%;
+  }
+  .offset-xl-6 {
+    margin-left: 50%;
+  }
+  .offset-xl-7 {
+    margin-left: 58.333333%;
+  }
+  .offset-xl-8 {
+    margin-left: 66.666667%;
+  }
+  .offset-xl-9 {
+    margin-left: 75%;
+  }
+  .offset-xl-10 {
+    margin-left: 83.333333%;
+  }
+  .offset-xl-11 {
+    margin-left: 91.666667%;
+  }
+}
+
+.table {
+  width: 100%;
+  max-width: 100%;
+  margin-bottom: 1rem;
+  background-color: transparent;
+}
+
+.table th,
+.table td {
+  padding: 0.75rem;
+  vertical-align: top;
+  border-top: 1px solid #e9ecef;
+}
+
+.table thead th {
+  vertical-align: bottom;
+  border-bottom: 2px solid #e9ecef;
+}
+
+.table tbody + tbody {
+  border-top: 2px solid #e9ecef;
+}
+
+.table .table {
+  background-color: #fff;
+}
+
+.table-sm th,
+.table-sm td {
+  padding: 0.3rem;
+}
+
+.table-bordered {
+  border: 1px solid #e9ecef;
+}
+
+.table-bordered th,
+.table-bordered td {
+  border: 1px solid #e9ecef;
+}
+
+.table-bordered thead th,
+.table-bordered thead td {
+  border-bottom-width: 2px;
+}
+
+.table-striped tbody tr:nth-of-type(odd) {
+  background-color: rgba(0, 0, 0, 0.05);
+}
+
+.table-hover tbody tr:hover {
+  background-color: rgba(0, 0, 0, 0.075);
+}
+
+.table-primary,
+.table-primary > th,
+.table-primary > td {
+  background-color: #b8daff;
+}
+
+.table-hover .table-primary:hover {
+  background-color: #9fcdff;
+}
+
+.table-hover .table-primary:hover > td,
+.table-hover .table-primary:hover > th {
+  background-color: #9fcdff;
+}
+
+.table-secondary,
+.table-secondary > th,
+.table-secondary > td {
+  background-color: #dddfe2;
+}
+
+.table-hover .table-secondary:hover {
+  background-color: #cfd2d6;
+}
+
+.table-hover .table-secondary:hover > td,
+.table-hover .table-secondary:hover > th {
+  background-color: #cfd2d6;
+}
+
+.table-success,
+.table-success > th,
+.table-success > td {
+  background-color: #c3e6cb;
+}
+
+.table-hover .table-success:hover {
+  background-color: #b1dfbb;
+}
+
+.table-hover .table-success:hover > td,
+.table-hover .table-success:hover > th {
+  background-color: #b1dfbb;
+}
+
+.table-info,
+.table-info > th,
+.table-info > td {
+  background-color: #bee5eb;
+}
+
+.table-hover .table-info:hover {
+  background-color: #abdde5;
+}
+
+.table-hover .table-info:hover > td,
+.table-hover .table-info:hover > th {
+  background-color: #abdde5;
+}
+
+.table-warning,
+.table-warning > th,
+.table-warning > td {
+  background-color: #ffeeba;
+}
+
+.table-hover .table-warning:hover {
+  background-color: #ffe8a1;
+}
+
+.table-hover .table-warning:hover > td,
+.table-hover .table-warning:hover > th {
+  background-color: #ffe8a1;
+}
+
+.table-danger,
+.table-danger > th,
+.table-danger > td {
+  background-color: #f5c6cb;
+}
+
+.table-hover .table-danger:hover {
+  background-color: #f1b0b7;
+}
+
+.table-hover .table-danger:hover > td,
+.table-hover .table-danger:hover > th {
+  background-color: #f1b0b7;
+}
+
+.table-light,
+.table-light > th,
+.table-light > td {
+  background-color: #fdfdfe;
+}
+
+.table-hover .table-light:hover {
+  background-color: #ececf6;
+}
+
+.table-hover .table-light:hover > td,
+.table-hover .table-light:hover > th {
+  background-color: #ececf6;
+}
+
+.table-dark,
+.table-dark > th,
+.table-dark > td {
+  background-color: #c6c8ca;
+}
+
+.table-hover .table-dark:hover {
+  background-color: #b9bbbe;
+}
+
+.table-hover .table-dark:hover > td,
+.table-hover .table-dark:hover > th {
+  background-color: #b9bbbe;
+}
+
+.table-active,
+.table-active > th,
+.table-active > td {
+  background-color: rgba(0, 0, 0, 0.075);
+}
+
+.table-hover .table-active:hover {
+  background-color: rgba(0, 0, 0, 0.075);
+}
+
+.table-hover .table-active:hover > td,
+.table-hover .table-active:hover > th {
+  background-color: rgba(0, 0, 0, 0.075);
+}
+
+.table .thead-dark th {
+  color: #fff;
+  background-color: #212529;
+  border-color: #32383e;
+}
+
+.table .thead-light th {
+  color: #495057;
+  background-color: #e9ecef;
+  border-color: #e9ecef;
+}
+
+.table-dark {
+  color: #fff;
+  background-color: #212529;
+}
+
+.table-dark th,
+.table-dark td,
+.table-dark thead th {
+  border-color: #32383e;
+}
+
+.table-dark.table-bordered {
+  border: 0;
+}
+
+.table-dark.table-striped tbody tr:nth-of-type(odd) {
+  background-color: rgba(255, 255, 255, 0.05);
+}
+
+.table-dark.table-hover tbody tr:hover {
+  background-color: rgba(255, 255, 255, 0.075);
+}
+
+@media (max-width: 575px) {
+  .table-responsive-sm {
+    display: block;
+    width: 100%;
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+  }
+  .table-responsive-sm.table-bordered {
+    border: 0;
+  }
+}
+
+@media (max-width: 767px) {
+  .table-responsive-md {
+    display: block;
+    width: 100%;
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+  }
+  .table-responsive-md.table-bordered {
+    border: 0;
+  }
+}
+
+@media (max-width: 991px) {
+  .table-responsive-lg {
+    display: block;
+    width: 100%;
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+  }
+  .table-responsive-lg.table-bordered {
+    border: 0;
+  }
+}
+
+@media (max-width: 1199px) {
+  .table-responsive-xl {
+    display: block;
+    width: 100%;
+    overflow-x: auto;
+    -webkit-overflow-scrolling: touch;
+    -ms-overflow-style: -ms-autohiding-scrollbar;
+  }
+  .table-responsive-xl.table-bordered {
+    border: 0;
+  }
+}
+
+.table-responsive {
+  display: block;
+  width: 100%;
+  overflow-x: auto;
+  -webkit-overflow-scrolling: touch;
+  -ms-overflow-style: -ms-autohiding-scrollbar;
+}
+
+.table-responsive.table-bordered {
+  border: 0;
+}
+
+.form-control {
+  display: block;
+  width: 100%;
+  padding: 0.375rem 0.75rem;
+  font-size: 1rem;
+  line-height: 1.5;
+  color: #495057;
+  background-color: #fff;
+  background-image: none;
+  background-clip: padding-box;
+  border: 1px solid #ced4da;
+  border-radius: 0.25rem;
+  transition: border-color ease-in-out 0.15s, box-shadow ease-in-out 0.15s;
+}
+
+.form-control::-ms-expand {
+  background-color: transparent;
+  border: 0;
+}
+
+.form-control:focus {
+  color: #495057;
+  background-color: #fff;
+  border-color: #80bdff;
+  outline: none;
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+}
+
+.form-control::-webkit-input-placeholder {
+  color: #868e96;
+  opacity: 1;
+}
+
+.form-control:-ms-input-placeholder {
+  color: #868e96;
+  opacity: 1;
+}
+
+.form-control::-ms-input-placeholder {
+  color: #868e96;
+  opacity: 1;
+}
+
+.form-control::placeholder {
+  color: #868e96;
+  opacity: 1;
+}
+
+.form-control:disabled, .form-control[readonly] {
+  background-color: #e9ecef;
+  opacity: 1;
+}
+
+select.form-control:not([size]):not([multiple]) {
+  height: calc(2.25rem + 2px);
+}
+
+select.form-control:focus::-ms-value {
+  color: #495057;
+  background-color: #fff;
+}
+
+.form-control-file,
+.form-control-range {
+  display: block;
+}
+
+.col-form-label {
+  padding-top: calc(0.375rem + 1px);
+  padding-bottom: calc(0.375rem + 1px);
+  margin-bottom: 0;
+  line-height: 1.5;
+}
+
+.col-form-label-lg {
+  padding-top: calc(0.5rem + 1px);
+  padding-bottom: calc(0.5rem + 1px);
+  font-size: 1.25rem;
+  line-height: 1.5;
+}
+
+.col-form-label-sm {
+  padding-top: calc(0.25rem + 1px);
+  padding-bottom: calc(0.25rem + 1px);
+  font-size: 0.875rem;
+  line-height: 1.5;
+}
+
+.col-form-legend {
+  padding-top: 0.375rem;
+  padding-bottom: 0.375rem;
+  margin-bottom: 0;
+  font-size: 1rem;
+}
+
+.form-control-plaintext {
+  padding-top: 0.375rem;
+  padding-bottom: 0.375rem;
+  margin-bottom: 0;
+  line-height: 1.5;
+  background-color: transparent;
+  border: solid transparent;
+  border-width: 1px 0;
+}
+
+.form-control-plaintext.form-control-sm, .input-group-sm > .form-control-plaintext.form-control,
+.input-group-sm > .form-control-plaintext.input-group-addon,
+.input-group-sm > .input-group-btn > .form-control-plaintext.btn, .form-control-plaintext.form-control-lg, 
.input-group-lg > .form-control-plaintext.form-control,
+.input-group-lg > .form-control-plaintext.input-group-addon,
+.input-group-lg > .input-group-btn > .form-control-plaintext.btn {
+  padding-right: 0;
+  padding-left: 0;
+}
+
+.form-control-sm, .input-group-sm > .form-control,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .btn {
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  line-height: 1.5;
+  border-radius: 0.2rem;
+}
+
+select.form-control-sm:not([size]):not([multiple]), .input-group-sm > 
select.form-control:not([size]):not([multiple]),
+.input-group-sm > select.input-group-addon:not([size]):not([multiple]),
+.input-group-sm > .input-group-btn > select.btn:not([size]):not([multiple]) {
+  height: calc(1.8125rem + 2px);
+}
+
+.form-control-lg, .input-group-lg > .form-control,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .btn {
+  padding: 0.5rem 1rem;
+  font-size: 1.25rem;
+  line-height: 1.5;
+  border-radius: 0.3rem;
+}
+
+select.form-control-lg:not([size]):not([multiple]), .input-group-lg > 
select.form-control:not([size]):not([multiple]),
+.input-group-lg > select.input-group-addon:not([size]):not([multiple]),
+.input-group-lg > .input-group-btn > select.btn:not([size]):not([multiple]) {
+  height: calc(2.875rem + 2px);
+}
+
+.form-group {
+  margin-bottom: 1rem;
+}
+
+.form-text {
+  display: block;
+  margin-top: 0.25rem;
+}
+
+.form-row {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  margin-right: -5px;
+  margin-left: -5px;
+}
+
+.form-row > .col,
+.form-row > [class*="col-"] {
+  padding-right: 5px;
+  padding-left: 5px;
+}
+
+.form-check {
+  position: relative;
+  display: block;
+  margin-bottom: 0.5rem;
+}
+
+.form-check.disabled .form-check-label {
+  color: #868e96;
+}
+
+.form-check-label {
+  padding-left: 1.25rem;
+  margin-bottom: 0;
+}
+
+.form-check-input {
+  position: absolute;
+  margin-top: 0.25rem;
+  margin-left: -1.25rem;
+}
+
+.form-check-inline {
+  display: inline-block;
+  margin-right: 0.75rem;
+}
+
+.form-check-inline .form-check-label {
+  vertical-align: middle;
+}
+
+.valid-feedback {
+  display: none;
+  margin-top: .25rem;
+  font-size: .875rem;
+  color: #28a745;
+}
+
+.valid-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  width: 250px;
+  padding: .5rem;
+  margin-top: .1rem;
+  font-size: .875rem;
+  line-height: 1;
+  color: #fff;
+  background-color: rgba(40, 167, 69, 0.8);
+  border-radius: .2rem;
+}
+
+.was-validated .form-control:valid, .form-control.is-valid, .was-validated
+.custom-select:valid,
+.custom-select.is-valid {
+  border-color: #28a745;
+}
+
+.was-validated .form-control:valid:focus, .form-control.is-valid:focus, .was-validated
+.custom-select:valid:focus,
+.custom-select.is-valid:focus {
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
+}
+
+.was-validated .form-control:valid ~ .valid-feedback,
+.was-validated .form-control:valid ~ .valid-tooltip, .form-control.is-valid ~ .valid-feedback,
+.form-control.is-valid ~ .valid-tooltip, .was-validated
+.custom-select:valid ~ .valid-feedback,
+.was-validated
+.custom-select:valid ~ .valid-tooltip,
+.custom-select.is-valid ~ .valid-feedback,
+.custom-select.is-valid ~ .valid-tooltip {
+  display: block;
+}
+
+.was-validated .form-check-input:valid + .form-check-label, .form-check-input.is-valid + .form-check-label {
+  color: #28a745;
+}
+
+.was-validated .custom-control-input:valid ~ .custom-control-indicator, .custom-control-input.is-valid ~ 
.custom-control-indicator {
+  background-color: rgba(40, 167, 69, 0.25);
+}
+
+.was-validated .custom-control-input:valid ~ .custom-control-description, .custom-control-input.is-valid ~ 
.custom-control-description {
+  color: #28a745;
+}
+
+.was-validated .custom-file-input:valid ~ .custom-file-control, .custom-file-input.is-valid ~ 
.custom-file-control {
+  border-color: #28a745;
+}
+
+.was-validated .custom-file-input:valid ~ .custom-file-control::before, .custom-file-input.is-valid ~ 
.custom-file-control::before {
+  border-color: inherit;
+}
+
+.was-validated .custom-file-input:valid:focus, .custom-file-input.is-valid:focus {
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.25);
+}
+
+.invalid-feedback {
+  display: none;
+  margin-top: .25rem;
+  font-size: .875rem;
+  color: #dc3545;
+}
+
+.invalid-tooltip {
+  position: absolute;
+  top: 100%;
+  z-index: 5;
+  display: none;
+  width: 250px;
+  padding: .5rem;
+  margin-top: .1rem;
+  font-size: .875rem;
+  line-height: 1;
+  color: #fff;
+  background-color: rgba(220, 53, 69, 0.8);
+  border-radius: .2rem;
+}
+
+.was-validated .form-control:invalid, .form-control.is-invalid, .was-validated
+.custom-select:invalid,
+.custom-select.is-invalid {
+  border-color: #dc3545;
+}
+
+.was-validated .form-control:invalid:focus, .form-control.is-invalid:focus, .was-validated
+.custom-select:invalid:focus,
+.custom-select.is-invalid:focus {
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
+}
+
+.was-validated .form-control:invalid ~ .invalid-feedback,
+.was-validated .form-control:invalid ~ .invalid-tooltip, .form-control.is-invalid ~ .invalid-feedback,
+.form-control.is-invalid ~ .invalid-tooltip, .was-validated
+.custom-select:invalid ~ .invalid-feedback,
+.was-validated
+.custom-select:invalid ~ .invalid-tooltip,
+.custom-select.is-invalid ~ .invalid-feedback,
+.custom-select.is-invalid ~ .invalid-tooltip {
+  display: block;
+}
+
+.was-validated .form-check-input:invalid + .form-check-label, .form-check-input.is-invalid + 
.form-check-label {
+  color: #dc3545;
+}
+
+.was-validated .custom-control-input:invalid ~ .custom-control-indicator, .custom-control-input.is-invalid ~ 
.custom-control-indicator {
+  background-color: rgba(220, 53, 69, 0.25);
+}
+
+.was-validated .custom-control-input:invalid ~ .custom-control-description, .custom-control-input.is-invalid 
~ .custom-control-description {
+  color: #dc3545;
+}
+
+.was-validated .custom-file-input:invalid ~ .custom-file-control, .custom-file-input.is-invalid ~ 
.custom-file-control {
+  border-color: #dc3545;
+}
+
+.was-validated .custom-file-input:invalid ~ .custom-file-control::before, .custom-file-input.is-invalid ~ 
.custom-file-control::before {
+  border-color: inherit;
+}
+
+.was-validated .custom-file-input:invalid:focus, .custom-file-input.is-invalid:focus {
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.25);
+}
+
+.form-inline {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-flow: row wrap;
+      flex-flow: row wrap;
+  -ms-flex-align: center;
+      align-items: center;
+}
+
+.form-inline .form-check {
+  width: 100%;
+}
+
+@media (min-width: 576px) {
+  .form-inline label {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-align: center;
+        align-items: center;
+    -ms-flex-pack: center;
+        justify-content: center;
+    margin-bottom: 0;
+  }
+  .form-inline .form-group {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex: 0 0 auto;
+        flex: 0 0 auto;
+    -ms-flex-flow: row wrap;
+        flex-flow: row wrap;
+    -ms-flex-align: center;
+        align-items: center;
+    margin-bottom: 0;
+  }
+  .form-inline .form-control {
+    display: inline-block;
+    width: auto;
+    vertical-align: middle;
+  }
+  .form-inline .form-control-plaintext {
+    display: inline-block;
+  }
+  .form-inline .input-group {
+    width: auto;
+  }
+  .form-inline .form-check {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-align: center;
+        align-items: center;
+    -ms-flex-pack: center;
+        justify-content: center;
+    width: auto;
+    margin-top: 0;
+    margin-bottom: 0;
+  }
+  .form-inline .form-check-label {
+    padding-left: 0;
+  }
+  .form-inline .form-check-input {
+    position: relative;
+    margin-top: 0;
+    margin-right: 0.25rem;
+    margin-left: 0;
+  }
+  .form-inline .custom-control {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex-align: center;
+        align-items: center;
+    -ms-flex-pack: center;
+        justify-content: center;
+    padding-left: 0;
+  }
+  .form-inline .custom-control-indicator {
+    position: static;
+    display: inline-block;
+    margin-right: 0.25rem;
+    vertical-align: text-bottom;
+  }
+  .form-inline .has-feedback .form-control-feedback {
+    top: 0;
+  }
+}
+
+.btn {
+  display: inline-block;
+  font-weight: 400;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: middle;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  border: 1px solid transparent;
+  padding: 0.375rem 0.75rem;
+  font-size: 1rem;
+  line-height: 1.5;
+  border-radius: 0.25rem;
+  transition: background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s 
ease-in-out;
+}
+
+.btn:focus, .btn:hover {
+  text-decoration: none;
+}
+
+.btn:focus, .btn.focus {
+  outline: 0;
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+}
+
+.btn.disabled, .btn:disabled {
+  opacity: .65;
+}
+
+.btn:not([disabled]):not(.disabled):active, .btn:not([disabled]):not(.disabled).active {
+  background-image: none;
+}
+
+a.btn.disabled,
+fieldset[disabled] a.btn {
+  pointer-events: none;
+}
+
+.btn-primary {
+  color: #fff;
+  background-color: #007bff;
+  border-color: #007bff;
+}
+
+.btn-primary:hover {
+  color: #fff;
+  background-color: #0069d9;
+  border-color: #0062cc;
+}
+
+.btn-primary:focus, .btn-primary.focus {
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
+}
+
+.btn-primary.disabled, .btn-primary:disabled {
+  background-color: #007bff;
+  border-color: #007bff;
+}
+
+.btn-primary:not([disabled]):not(.disabled):active, .btn-primary:not([disabled]):not(.disabled).active,
+.show > .btn-primary.dropdown-toggle {
+  color: #fff;
+  background-color: #0062cc;
+  border-color: #005cbf;
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
+}
+
+.btn-secondary {
+  color: #fff;
+  background-color: #868e96;
+  border-color: #868e96;
+}
+
+.btn-secondary:hover {
+  color: #fff;
+  background-color: #727b84;
+  border-color: #6c757d;
+}
+
+.btn-secondary:focus, .btn-secondary.focus {
+  box-shadow: 0 0 0 0.2rem rgba(134, 142, 150, 0.5);
+}
+
+.btn-secondary.disabled, .btn-secondary:disabled {
+  background-color: #868e96;
+  border-color: #868e96;
+}
+
+.btn-secondary:not([disabled]):not(.disabled):active, .btn-secondary:not([disabled]):not(.disabled).active,
+.show > .btn-secondary.dropdown-toggle {
+  color: #fff;
+  background-color: #6c757d;
+  border-color: #666e76;
+  box-shadow: 0 0 0 0.2rem rgba(134, 142, 150, 0.5);
+}
+
+.btn-success {
+  color: #fff;
+  background-color: #28a745;
+  border-color: #28a745;
+}
+
+.btn-success:hover {
+  color: #fff;
+  background-color: #218838;
+  border-color: #1e7e34;
+}
+
+.btn-success:focus, .btn-success.focus {
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
+}
+
+.btn-success.disabled, .btn-success:disabled {
+  background-color: #28a745;
+  border-color: #28a745;
+}
+
+.btn-success:not([disabled]):not(.disabled):active, .btn-success:not([disabled]):not(.disabled).active,
+.show > .btn-success.dropdown-toggle {
+  color: #fff;
+  background-color: #1e7e34;
+  border-color: #1c7430;
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
+}
+
+.btn-info {
+  color: #fff;
+  background-color: #17a2b8;
+  border-color: #17a2b8;
+}
+
+.btn-info:hover {
+  color: #fff;
+  background-color: #138496;
+  border-color: #117a8b;
+}
+
+.btn-info:focus, .btn-info.focus {
+  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
+}
+
+.btn-info.disabled, .btn-info:disabled {
+  background-color: #17a2b8;
+  border-color: #17a2b8;
+}
+
+.btn-info:not([disabled]):not(.disabled):active, .btn-info:not([disabled]):not(.disabled).active,
+.show > .btn-info.dropdown-toggle {
+  color: #fff;
+  background-color: #117a8b;
+  border-color: #10707f;
+  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
+}
+
+.btn-warning {
+  color: #111;
+  background-color: #ffc107;
+  border-color: #ffc107;
+}
+
+.btn-warning:hover {
+  color: #111;
+  background-color: #e0a800;
+  border-color: #d39e00;
+}
+
+.btn-warning:focus, .btn-warning.focus {
+  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
+}
+
+.btn-warning.disabled, .btn-warning:disabled {
+  background-color: #ffc107;
+  border-color: #ffc107;
+}
+
+.btn-warning:not([disabled]):not(.disabled):active, .btn-warning:not([disabled]):not(.disabled).active,
+.show > .btn-warning.dropdown-toggle {
+  color: #111;
+  background-color: #d39e00;
+  border-color: #c69500;
+  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
+}
+
+.btn-danger {
+  color: #fff;
+  background-color: #dc3545;
+  border-color: #dc3545;
+}
+
+.btn-danger:hover {
+  color: #fff;
+  background-color: #c82333;
+  border-color: #bd2130;
+}
+
+.btn-danger:focus, .btn-danger.focus {
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
+}
+
+.btn-danger.disabled, .btn-danger:disabled {
+  background-color: #dc3545;
+  border-color: #dc3545;
+}
+
+.btn-danger:not([disabled]):not(.disabled):active, .btn-danger:not([disabled]):not(.disabled).active,
+.show > .btn-danger.dropdown-toggle {
+  color: #fff;
+  background-color: #bd2130;
+  border-color: #b21f2d;
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
+}
+
+.btn-light {
+  color: #111;
+  background-color: #f8f9fa;
+  border-color: #f8f9fa;
+}
+
+.btn-light:hover {
+  color: #111;
+  background-color: #e2e6ea;
+  border-color: #dae0e5;
+}
+
+.btn-light:focus, .btn-light.focus {
+  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
+}
+
+.btn-light.disabled, .btn-light:disabled {
+  background-color: #f8f9fa;
+  border-color: #f8f9fa;
+}
+
+.btn-light:not([disabled]):not(.disabled):active, .btn-light:not([disabled]):not(.disabled).active,
+.show > .btn-light.dropdown-toggle {
+  color: #111;
+  background-color: #dae0e5;
+  border-color: #d3d9df;
+  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
+}
+
+.btn-dark {
+  color: #fff;
+  background-color: #343a40;
+  border-color: #343a40;
+}
+
+.btn-dark:hover {
+  color: #fff;
+  background-color: #23272b;
+  border-color: #1d2124;
+}
+
+.btn-dark:focus, .btn-dark.focus {
+  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
+}
+
+.btn-dark.disabled, .btn-dark:disabled {
+  background-color: #343a40;
+  border-color: #343a40;
+}
+
+.btn-dark:not([disabled]):not(.disabled):active, .btn-dark:not([disabled]):not(.disabled).active,
+.show > .btn-dark.dropdown-toggle {
+  color: #fff;
+  background-color: #1d2124;
+  border-color: #171a1d;
+  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
+}
+
+.btn-outline-primary {
+  color: #007bff;
+  background-color: transparent;
+  background-image: none;
+  border-color: #007bff;
+}
+
+.btn-outline-primary:hover {
+  color: #fff;
+  background-color: #007bff;
+  border-color: #007bff;
+}
+
+.btn-outline-primary:focus, .btn-outline-primary.focus {
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
+}
+
+.btn-outline-primary.disabled, .btn-outline-primary:disabled {
+  color: #007bff;
+  background-color: transparent;
+}
+
+.btn-outline-primary:not([disabled]):not(.disabled):active, 
.btn-outline-primary:not([disabled]):not(.disabled).active,
+.show > .btn-outline-primary.dropdown-toggle {
+  color: #fff;
+  background-color: #007bff;
+  border-color: #007bff;
+  box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.5);
+}
+
+.btn-outline-secondary {
+  color: #868e96;
+  background-color: transparent;
+  background-image: none;
+  border-color: #868e96;
+}
+
+.btn-outline-secondary:hover {
+  color: #fff;
+  background-color: #868e96;
+  border-color: #868e96;
+}
+
+.btn-outline-secondary:focus, .btn-outline-secondary.focus {
+  box-shadow: 0 0 0 0.2rem rgba(134, 142, 150, 0.5);
+}
+
+.btn-outline-secondary.disabled, .btn-outline-secondary:disabled {
+  color: #868e96;
+  background-color: transparent;
+}
+
+.btn-outline-secondary:not([disabled]):not(.disabled):active, 
.btn-outline-secondary:not([disabled]):not(.disabled).active,
+.show > .btn-outline-secondary.dropdown-toggle {
+  color: #fff;
+  background-color: #868e96;
+  border-color: #868e96;
+  box-shadow: 0 0 0 0.2rem rgba(134, 142, 150, 0.5);
+}
+
+.btn-outline-success {
+  color: #28a745;
+  background-color: transparent;
+  background-image: none;
+  border-color: #28a745;
+}
+
+.btn-outline-success:hover {
+  color: #fff;
+  background-color: #28a745;
+  border-color: #28a745;
+}
+
+.btn-outline-success:focus, .btn-outline-success.focus {
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
+}
+
+.btn-outline-success.disabled, .btn-outline-success:disabled {
+  color: #28a745;
+  background-color: transparent;
+}
+
+.btn-outline-success:not([disabled]):not(.disabled):active, 
.btn-outline-success:not([disabled]):not(.disabled).active,
+.show > .btn-outline-success.dropdown-toggle {
+  color: #fff;
+  background-color: #28a745;
+  border-color: #28a745;
+  box-shadow: 0 0 0 0.2rem rgba(40, 167, 69, 0.5);
+}
+
+.btn-outline-info {
+  color: #17a2b8;
+  background-color: transparent;
+  background-image: none;
+  border-color: #17a2b8;
+}
+
+.btn-outline-info:hover {
+  color: #fff;
+  background-color: #17a2b8;
+  border-color: #17a2b8;
+}
+
+.btn-outline-info:focus, .btn-outline-info.focus {
+  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
+}
+
+.btn-outline-info.disabled, .btn-outline-info:disabled {
+  color: #17a2b8;
+  background-color: transparent;
+}
+
+.btn-outline-info:not([disabled]):not(.disabled):active, 
.btn-outline-info:not([disabled]):not(.disabled).active,
+.show > .btn-outline-info.dropdown-toggle {
+  color: #fff;
+  background-color: #17a2b8;
+  border-color: #17a2b8;
+  box-shadow: 0 0 0 0.2rem rgba(23, 162, 184, 0.5);
+}
+
+.btn-outline-warning {
+  color: #ffc107;
+  background-color: transparent;
+  background-image: none;
+  border-color: #ffc107;
+}
+
+.btn-outline-warning:hover {
+  color: #fff;
+  background-color: #ffc107;
+  border-color: #ffc107;
+}
+
+.btn-outline-warning:focus, .btn-outline-warning.focus {
+  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
+}
+
+.btn-outline-warning.disabled, .btn-outline-warning:disabled {
+  color: #ffc107;
+  background-color: transparent;
+}
+
+.btn-outline-warning:not([disabled]):not(.disabled):active, 
.btn-outline-warning:not([disabled]):not(.disabled).active,
+.show > .btn-outline-warning.dropdown-toggle {
+  color: #fff;
+  background-color: #ffc107;
+  border-color: #ffc107;
+  box-shadow: 0 0 0 0.2rem rgba(255, 193, 7, 0.5);
+}
+
+.btn-outline-danger {
+  color: #dc3545;
+  background-color: transparent;
+  background-image: none;
+  border-color: #dc3545;
+}
+
+.btn-outline-danger:hover {
+  color: #fff;
+  background-color: #dc3545;
+  border-color: #dc3545;
+}
+
+.btn-outline-danger:focus, .btn-outline-danger.focus {
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
+}
+
+.btn-outline-danger.disabled, .btn-outline-danger:disabled {
+  color: #dc3545;
+  background-color: transparent;
+}
+
+.btn-outline-danger:not([disabled]):not(.disabled):active, 
.btn-outline-danger:not([disabled]):not(.disabled).active,
+.show > .btn-outline-danger.dropdown-toggle {
+  color: #fff;
+  background-color: #dc3545;
+  border-color: #dc3545;
+  box-shadow: 0 0 0 0.2rem rgba(220, 53, 69, 0.5);
+}
+
+.btn-outline-light {
+  color: #f8f9fa;
+  background-color: transparent;
+  background-image: none;
+  border-color: #f8f9fa;
+}
+
+.btn-outline-light:hover {
+  color: #212529;
+  background-color: #f8f9fa;
+  border-color: #f8f9fa;
+}
+
+.btn-outline-light:focus, .btn-outline-light.focus {
+  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
+}
+
+.btn-outline-light.disabled, .btn-outline-light:disabled {
+  color: #f8f9fa;
+  background-color: transparent;
+}
+
+.btn-outline-light:not([disabled]):not(.disabled):active, 
.btn-outline-light:not([disabled]):not(.disabled).active,
+.show > .btn-outline-light.dropdown-toggle {
+  color: #212529;
+  background-color: #f8f9fa;
+  border-color: #f8f9fa;
+  box-shadow: 0 0 0 0.2rem rgba(248, 249, 250, 0.5);
+}
+
+.btn-outline-dark {
+  color: #343a40;
+  background-color: transparent;
+  background-image: none;
+  border-color: #343a40;
+}
+
+.btn-outline-dark:hover {
+  color: #fff;
+  background-color: #343a40;
+  border-color: #343a40;
+}
+
+.btn-outline-dark:focus, .btn-outline-dark.focus {
+  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
+}
+
+.btn-outline-dark.disabled, .btn-outline-dark:disabled {
+  color: #343a40;
+  background-color: transparent;
+}
+
+.btn-outline-dark:not([disabled]):not(.disabled):active, 
.btn-outline-dark:not([disabled]):not(.disabled).active,
+.show > .btn-outline-dark.dropdown-toggle {
+  color: #fff;
+  background-color: #343a40;
+  border-color: #343a40;
+  box-shadow: 0 0 0 0.2rem rgba(52, 58, 64, 0.5);
+}
+
+.btn-link {
+  font-weight: 400;
+  color: #007bff;
+  background-color: transparent;
+}
+
+.btn-link:hover {
+  color: #0056b3;
+  text-decoration: underline;
+  background-color: transparent;
+  border-color: transparent;
+}
+
+.btn-link:focus, .btn-link.focus {
+  border-color: transparent;
+  box-shadow: none;
+}
+
+.btn-link:disabled, .btn-link.disabled {
+  color: #868e96;
+}
+
+.btn-lg, .btn-group-lg > .btn {
+  padding: 0.5rem 1rem;
+  font-size: 1.25rem;
+  line-height: 1.5;
+  border-radius: 0.3rem;
+}
+
+.btn-sm, .btn-group-sm > .btn {
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  line-height: 1.5;
+  border-radius: 0.2rem;
+}
+
+.btn-block {
+  display: block;
+  width: 100%;
+}
+
+.btn-block + .btn-block {
+  margin-top: 0.5rem;
+}
+
+input[type="submit"].btn-block,
+input[type="reset"].btn-block,
+input[type="button"].btn-block {
+  width: 100%;
+}
+
+.fade {
+  opacity: 0;
+  transition: opacity 0.15s linear;
+}
+
+.fade.show {
+  opacity: 1;
+}
+
+.collapse {
+  display: none;
+}
+
+.collapse.show {
+  display: block;
+}
+
+tr.collapse.show {
+  display: table-row;
+}
+
+tbody.collapse.show {
+  display: table-row-group;
+}
+
+.collapsing {
+  position: relative;
+  height: 0;
+  overflow: hidden;
+  transition: height 0.35s ease;
+}
+
+.dropup,
+.dropdown {
+  position: relative;
+}
+
+.dropdown-toggle::after {
+  display: inline-block;
+  width: 0;
+  height: 0;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0.3em solid;
+  border-right: 0.3em solid transparent;
+  border-bottom: 0;
+  border-left: 0.3em solid transparent;
+}
+
+.dropdown-toggle:empty::after {
+  margin-left: 0;
+}
+
+.dropdown-menu {
+  position: absolute;
+  top: 100%;
+  left: 0;
+  z-index: 1000;
+  display: none;
+  float: left;
+  min-width: 10rem;
+  padding: 0.5rem 0;
+  margin: 0.125rem 0 0;
+  font-size: 1rem;
+  color: #212529;
+  text-align: left;
+  list-style: none;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.15);
+  border-radius: 0.25rem;
+}
+
+.dropup .dropdown-menu {
+  margin-top: 0;
+  margin-bottom: 0.125rem;
+}
+
+.dropup .dropdown-toggle::after {
+  display: inline-block;
+  width: 0;
+  height: 0;
+  margin-left: 0.255em;
+  vertical-align: 0.255em;
+  content: "";
+  border-top: 0;
+  border-right: 0.3em solid transparent;
+  border-bottom: 0.3em solid;
+  border-left: 0.3em solid transparent;
+}
+
+.dropup .dropdown-toggle:empty::after {
+  margin-left: 0;
+}
+
+.dropdown-divider {
+  height: 0;
+  margin: 0.5rem 0;
+  overflow: hidden;
+  border-top: 1px solid #e9ecef;
+}
+
+.dropdown-item {
+  display: block;
+  width: 100%;
+  padding: 0.25rem 1.5rem;
+  clear: both;
+  font-weight: 400;
+  color: #212529;
+  text-align: inherit;
+  white-space: nowrap;
+  background: none;
+  border: 0;
+}
+
+.dropdown-item:focus, .dropdown-item:hover {
+  color: #16181b;
+  text-decoration: none;
+  background-color: #f8f9fa;
+}
+
+.dropdown-item.active, .dropdown-item:active {
+  color: #fff;
+  text-decoration: none;
+  background-color: #007bff;
+}
+
+.dropdown-item.disabled, .dropdown-item:disabled {
+  color: #868e96;
+  background-color: transparent;
+}
+
+.dropdown-menu.show {
+  display: block;
+}
+
+.dropdown-header {
+  display: block;
+  padding: 0.5rem 1.5rem;
+  margin-bottom: 0;
+  font-size: 0.875rem;
+  color: #868e96;
+  white-space: nowrap;
+}
+
+.btn-group,
+.btn-group-vertical {
+  position: relative;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  vertical-align: middle;
+}
+
+.btn-group > .btn,
+.btn-group-vertical > .btn {
+  position: relative;
+  -ms-flex: 0 1 auto;
+      flex: 0 1 auto;
+}
+
+.btn-group > .btn:hover,
+.btn-group-vertical > .btn:hover {
+  z-index: 2;
+}
+
+.btn-group > .btn:focus, .btn-group > .btn:active, .btn-group > .btn.active,
+.btn-group-vertical > .btn:focus,
+.btn-group-vertical > .btn:active,
+.btn-group-vertical > .btn.active {
+  z-index: 2;
+}
+
+.btn-group .btn + .btn,
+.btn-group .btn + .btn-group,
+.btn-group .btn-group + .btn,
+.btn-group .btn-group + .btn-group,
+.btn-group-vertical .btn + .btn,
+.btn-group-vertical .btn + .btn-group,
+.btn-group-vertical .btn-group + .btn,
+.btn-group-vertical .btn-group + .btn-group {
+  margin-left: -1px;
+}
+
+.btn-toolbar {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  -ms-flex-pack: start;
+      justify-content: flex-start;
+}
+
+.btn-toolbar .input-group {
+  width: auto;
+}
+
+.btn-group > .btn:not(:first-child):not(:last-child):not(.dropdown-toggle) {
+  border-radius: 0;
+}
+
+.btn-group > .btn:first-child {
+  margin-left: 0;
+}
+
+.btn-group > .btn:first-child:not(:last-child):not(.dropdown-toggle) {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.btn-group > .btn:last-child:not(:first-child),
+.btn-group > .dropdown-toggle:not(:first-child) {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.btn-group > .btn-group {
+  float: left;
+}
+
+.btn-group > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+
+.btn-group > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.btn-group > .btn-group:last-child:not(:first-child) > .btn:first-child {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.btn + .dropdown-toggle-split {
+  padding-right: 0.5625rem;
+  padding-left: 0.5625rem;
+}
+
+.btn + .dropdown-toggle-split::after {
+  margin-left: 0;
+}
+
+.btn-sm + .dropdown-toggle-split, .btn-group-sm > .btn + .dropdown-toggle-split {
+  padding-right: 0.375rem;
+  padding-left: 0.375rem;
+}
+
+.btn-lg + .dropdown-toggle-split, .btn-group-lg > .btn + .dropdown-toggle-split {
+  padding-right: 0.75rem;
+  padding-left: 0.75rem;
+}
+
+.btn-group-vertical {
+  -ms-flex-direction: column;
+      flex-direction: column;
+  -ms-flex-align: start;
+      align-items: flex-start;
+  -ms-flex-pack: center;
+      justify-content: center;
+}
+
+.btn-group-vertical .btn,
+.btn-group-vertical .btn-group {
+  width: 100%;
+}
+
+.btn-group-vertical > .btn + .btn,
+.btn-group-vertical > .btn + .btn-group,
+.btn-group-vertical > .btn-group + .btn,
+.btn-group-vertical > .btn-group + .btn-group {
+  margin-top: -1px;
+  margin-left: 0;
+}
+
+.btn-group-vertical > .btn:not(:first-child):not(:last-child) {
+  border-radius: 0;
+}
+
+.btn-group-vertical > .btn:first-child:not(:last-child) {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn:last-child:not(:first-child) {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:not(:first-child):not(:last-child) > .btn {
+  border-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .btn:last-child,
+.btn-group-vertical > .btn-group:first-child:not(:last-child) > .dropdown-toggle {
+  border-bottom-right-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.btn-group-vertical > .btn-group:last-child:not(:first-child) > .btn:first-child {
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+[data-toggle="buttons"] > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn input[type="checkbox"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="radio"],
+[data-toggle="buttons"] > .btn-group > .btn input[type="checkbox"] {
+  position: absolute;
+  clip: rect(0, 0, 0, 0);
+  pointer-events: none;
+}
+
+.input-group {
+  position: relative;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: stretch;
+      align-items: stretch;
+  width: 100%;
+}
+
+.input-group .form-control {
+  position: relative;
+  z-index: 2;
+  -ms-flex: 1 1 auto;
+      flex: 1 1 auto;
+  width: 1%;
+  margin-bottom: 0;
+}
+
+.input-group .form-control:focus, .input-group .form-control:active, .input-group .form-control:hover {
+  z-index: 3;
+}
+
+.input-group-addon,
+.input-group-btn,
+.input-group .form-control {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: center;
+      align-items: center;
+}
+
+.input-group-addon:not(:first-child):not(:last-child),
+.input-group-btn:not(:first-child):not(:last-child),
+.input-group .form-control:not(:first-child):not(:last-child) {
+  border-radius: 0;
+}
+
+.input-group-addon,
+.input-group-btn {
+  white-space: nowrap;
+}
+
+.input-group-addon {
+  padding: 0.375rem 0.75rem;
+  margin-bottom: 0;
+  font-size: 1rem;
+  font-weight: 400;
+  line-height: 1.5;
+  color: #495057;
+  text-align: center;
+  background-color: #e9ecef;
+  border: 1px solid #ced4da;
+  border-radius: 0.25rem;
+}
+
+.input-group-addon.form-control-sm,
+.input-group-sm > .input-group-addon,
+.input-group-sm > .input-group-btn > .input-group-addon.btn {
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  border-radius: 0.2rem;
+}
+
+.input-group-addon.form-control-lg,
+.input-group-lg > .input-group-addon,
+.input-group-lg > .input-group-btn > .input-group-addon.btn {
+  padding: 0.5rem 1rem;
+  font-size: 1.25rem;
+  border-radius: 0.3rem;
+}
+
+.input-group-addon input[type="radio"],
+.input-group-addon input[type="checkbox"] {
+  margin-top: 0;
+}
+
+.input-group .form-control:not(:last-child),
+.input-group-addon:not(:last-child),
+.input-group-btn:not(:last-child) > .btn,
+.input-group-btn:not(:last-child) > .btn-group > .btn,
+.input-group-btn:not(:last-child) > .dropdown-toggle,
+.input-group-btn:not(:first-child) > .btn:not(:last-child):not(.dropdown-toggle),
+.input-group-btn:not(:first-child) > .btn-group:not(:last-child) > .btn {
+  border-top-right-radius: 0;
+  border-bottom-right-radius: 0;
+}
+
+.input-group-addon:not(:last-child) {
+  border-right: 0;
+}
+
+.input-group .form-control:not(:first-child),
+.input-group-addon:not(:first-child),
+.input-group-btn:not(:first-child) > .btn,
+.input-group-btn:not(:first-child) > .btn-group > .btn,
+.input-group-btn:not(:first-child) > .dropdown-toggle,
+.input-group-btn:not(:last-child) > .btn:not(:first-child),
+.input-group-btn:not(:last-child) > .btn-group:not(:first-child) > .btn {
+  border-top-left-radius: 0;
+  border-bottom-left-radius: 0;
+}
+
+.form-control + .input-group-addon:not(:first-child) {
+  border-left: 0;
+}
+
+.input-group-btn {
+  position: relative;
+  -ms-flex-align: stretch;
+      align-items: stretch;
+  font-size: 0;
+  white-space: nowrap;
+}
+
+.input-group-btn > .btn {
+  position: relative;
+}
+
+.input-group-btn > .btn + .btn {
+  margin-left: -1px;
+}
+
+.input-group-btn > .btn:focus, .input-group-btn > .btn:active, .input-group-btn > .btn:hover {
+  z-index: 3;
+}
+
+.input-group-btn:first-child > .btn + .btn {
+  margin-left: 0;
+}
+
+.input-group-btn:not(:last-child) > .btn,
+.input-group-btn:not(:last-child) > .btn-group {
+  margin-right: -1px;
+}
+
+.input-group-btn:not(:first-child) > .btn,
+.input-group-btn:not(:first-child) > .btn-group {
+  z-index: 2;
+  margin-left: 0;
+}
+
+.input-group-btn:not(:first-child) > .btn:first-child,
+.input-group-btn:not(:first-child) > .btn-group:first-child {
+  margin-left: -1px;
+}
+
+.input-group-btn:not(:first-child) > .btn:focus, .input-group-btn:not(:first-child) > .btn:active, 
.input-group-btn:not(:first-child) > .btn:hover,
+.input-group-btn:not(:first-child) > .btn-group:focus,
+.input-group-btn:not(:first-child) > .btn-group:active,
+.input-group-btn:not(:first-child) > .btn-group:hover {
+  z-index: 3;
+}
+
+.custom-control {
+  position: relative;
+  display: -ms-inline-flexbox;
+  display: inline-flex;
+  min-height: 1.5rem;
+  padding-left: 1.5rem;
+  margin-right: 1rem;
+}
+
+.custom-control-input {
+  position: absolute;
+  z-index: -1;
+  opacity: 0;
+}
+
+.custom-control-input:checked ~ .custom-control-indicator {
+  color: #fff;
+  background-color: #007bff;
+}
+
+.custom-control-input:focus ~ .custom-control-indicator {
+  box-shadow: 0 0 0 1px #fff, 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
+}
+
+.custom-control-input:active ~ .custom-control-indicator {
+  color: #fff;
+  background-color: #b3d7ff;
+}
+
+.custom-control-input:disabled ~ .custom-control-indicator {
+  background-color: #e9ecef;
+}
+
+.custom-control-input:disabled ~ .custom-control-description {
+  color: #868e96;
+}
+
+.custom-control-indicator {
+  position: absolute;
+  top: 0.25rem;
+  left: 0;
+  display: block;
+  width: 1rem;
+  height: 1rem;
+  pointer-events: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  background-color: #ddd;
+  background-repeat: no-repeat;
+  background-position: center center;
+  background-size: 50% 50%;
+}
+
+.custom-checkbox .custom-control-indicator {
+  border-radius: 0.25rem;
+}
+
+.custom-checkbox .custom-control-input:checked ~ .custom-control-indicator {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 
viewBox='0 0 8 8'%3E%3Cpath fill='%23fff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 
2.193z'/%3E%3C/svg%3E");
+}
+
+.custom-checkbox .custom-control-input:indeterminate ~ .custom-control-indicator {
+  background-color: #007bff;
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 
viewBox='0 0 4 4'%3E%3Cpath stroke='%23fff' d='M0 2h4'/%3E%3C/svg%3E");
+}
+
+.custom-radio .custom-control-indicator {
+  border-radius: 50%;
+}
+
+.custom-radio .custom-control-input:checked ~ .custom-control-indicator {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 
viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23fff'/%3E%3C/svg%3E");
+}
+
+.custom-controls-stacked {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+}
+
+.custom-controls-stacked .custom-control {
+  margin-bottom: 0.25rem;
+}
+
+.custom-controls-stacked .custom-control + .custom-control {
+  margin-left: 0;
+}
+
+.custom-select {
+  display: inline-block;
+  max-width: 100%;
+  height: calc(2.25rem + 2px);
+  padding: 0.375rem 1.75rem 0.375rem 0.75rem;
+  line-height: 1.5;
+  color: #495057;
+  vertical-align: middle;
+  background: #fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 
0 4 5'%3E%3Cpath fill='%23333' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right 0.75rem center;
+  background-size: 8px 10px;
+  border: 1px solid #ced4da;
+  border-radius: 0.25rem;
+  -webkit-appearance: none;
+     -moz-appearance: none;
+          appearance: none;
+}
+
+.custom-select:focus {
+  border-color: #80bdff;
+  outline: none;
+}
+
+.custom-select:focus::-ms-value {
+  color: #495057;
+  background-color: #fff;
+}
+
+.custom-select[multiple] {
+  height: auto;
+  background-image: none;
+}
+
+.custom-select:disabled {
+  color: #868e96;
+  background-color: #e9ecef;
+}
+
+.custom-select::-ms-expand {
+  opacity: 0;
+}
+
+.custom-select-sm {
+  height: calc(1.8125rem + 2px);
+  padding-top: 0.375rem;
+  padding-bottom: 0.375rem;
+  font-size: 75%;
+}
+
+.custom-file {
+  position: relative;
+  display: inline-block;
+  max-width: 100%;
+  height: calc(2.25rem + 2px);
+  margin-bottom: 0;
+}
+
+.custom-file-input {
+  min-width: 14rem;
+  max-width: 100%;
+  height: calc(2.25rem + 2px);
+  margin: 0;
+  opacity: 0;
+}
+
+.custom-file-input:focus ~ .custom-file-control {
+  box-shadow: 0 0 0 0.075rem #fff, 0 0 0 0.2rem #007bff;
+}
+
+.custom-file-control {
+  position: absolute;
+  top: 0;
+  right: 0;
+  left: 0;
+  z-index: 5;
+  height: calc(2.25rem + 2px);
+  padding: 0.375rem 0.75rem;
+  line-height: 1.5;
+  color: #495057;
+  pointer-events: none;
+  -webkit-user-select: none;
+     -moz-user-select: none;
+      -ms-user-select: none;
+          user-select: none;
+  background-color: #fff;
+  border: 1px solid #ced4da;
+  border-radius: 0.25rem;
+}
+
+.custom-file-control:lang(en):empty::after {
+  content: "Choose file...";
+}
+
+.custom-file-control::before {
+  position: absolute;
+  top: -1px;
+  right: -1px;
+  bottom: -1px;
+  z-index: 6;
+  display: block;
+  height: calc(2.25rem + 2px);
+  padding: 0.375rem 0.75rem;
+  line-height: 1.5;
+  color: #495057;
+  background-color: #e9ecef;
+  border: 1px solid #ced4da;
+  border-radius: 0 0.25rem 0.25rem 0;
+}
+
+.custom-file-control:lang(en)::before {
+  content: "Browse";
+}
+
+.nav {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none;
+}
+
+.nav-link {
+  display: block;
+  padding: 0.5rem 1rem;
+}
+
+.nav-link:focus, .nav-link:hover {
+  text-decoration: none;
+}
+
+.nav-link.disabled {
+  color: #868e96;
+}
+
+.nav-tabs {
+  border-bottom: 1px solid #ddd;
+}
+
+.nav-tabs .nav-item {
+  margin-bottom: -1px;
+}
+
+.nav-tabs .nav-link {
+  border: 1px solid transparent;
+  border-top-left-radius: 0.25rem;
+  border-top-right-radius: 0.25rem;
+}
+
+.nav-tabs .nav-link:focus, .nav-tabs .nav-link:hover {
+  border-color: #e9ecef #e9ecef #ddd;
+}
+
+.nav-tabs .nav-link.disabled {
+  color: #868e96;
+  background-color: transparent;
+  border-color: transparent;
+}
+
+.nav-tabs .nav-link.active,
+.nav-tabs .nav-item.show .nav-link {
+  color: #495057;
+  background-color: #fff;
+  border-color: #ddd #ddd #fff;
+}
+
+.nav-tabs .dropdown-menu {
+  margin-top: -1px;
+  border-top-left-radius: 0;
+  border-top-right-radius: 0;
+}
+
+.nav-pills .nav-link {
+  border-radius: 0.25rem;
+}
+
+.nav-pills .nav-link.active,
+.nav-pills .show > .nav-link {
+  color: #fff;
+  background-color: #007bff;
+}
+
+.nav-fill .nav-item {
+  -ms-flex: 1 1 auto;
+      flex: 1 1 auto;
+  text-align: center;
+}
+
+.nav-justified .nav-item {
+  -ms-flex-preferred-size: 0;
+      flex-basis: 0;
+  -ms-flex-positive: 1;
+      flex-grow: 1;
+  text-align: center;
+}
+
+.tab-content > .tab-pane {
+  display: none;
+}
+
+.tab-content > .active {
+  display: block;
+}
+
+.navbar {
+  position: relative;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  -ms-flex-align: center;
+      align-items: center;
+  -ms-flex-pack: justify;
+      justify-content: space-between;
+  padding: 0.5rem 1rem;
+}
+
+.navbar > .container,
+.navbar > .container-fluid {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  -ms-flex-align: center;
+      align-items: center;
+  -ms-flex-pack: justify;
+      justify-content: space-between;
+}
+
+.navbar-brand {
+  display: inline-block;
+  padding-top: 0.3125rem;
+  padding-bottom: 0.3125rem;
+  margin-right: 1rem;
+  font-size: 1.25rem;
+  line-height: inherit;
+  white-space: nowrap;
+}
+
+.navbar-brand:focus, .navbar-brand:hover {
+  text-decoration: none;
+}
+
+.navbar-nav {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+  padding-left: 0;
+  margin-bottom: 0;
+  list-style: none;
+}
+
+.navbar-nav .nav-link {
+  padding-right: 0;
+  padding-left: 0;
+}
+
+.navbar-nav .dropdown-menu {
+  position: static;
+  float: none;
+}
+
+.navbar-text {
+  display: inline-block;
+  padding-top: 0.5rem;
+  padding-bottom: 0.5rem;
+}
+
+.navbar-collapse {
+  -ms-flex-preferred-size: 100%;
+      flex-basis: 100%;
+  -ms-flex-positive: 1;
+      flex-grow: 1;
+  -ms-flex-align: center;
+      align-items: center;
+}
+
+.navbar-toggler {
+  padding: 0.25rem 0.75rem;
+  font-size: 1.25rem;
+  line-height: 1;
+  background: transparent;
+  border: 1px solid transparent;
+  border-radius: 0.25rem;
+}
+
+.navbar-toggler:focus, .navbar-toggler:hover {
+  text-decoration: none;
+}
+
+.navbar-toggler-icon {
+  display: inline-block;
+  width: 1.5em;
+  height: 1.5em;
+  vertical-align: middle;
+  content: "";
+  background: no-repeat center center;
+  background-size: 100% 100%;
+}
+
+@media (max-width: 575px) {
+  .navbar-expand-sm > .container,
+  .navbar-expand-sm > .container-fluid {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+
+@media (min-width: 576px) {
+  .navbar-expand-sm {
+    -ms-flex-flow: row nowrap;
+        flex-flow: row nowrap;
+    -ms-flex-pack: start;
+        justify-content: flex-start;
+  }
+  .navbar-expand-sm .navbar-nav {
+    -ms-flex-direction: row;
+        flex-direction: row;
+  }
+  .navbar-expand-sm .navbar-nav .dropdown-menu {
+    position: absolute;
+  }
+  .navbar-expand-sm .navbar-nav .dropdown-menu-right {
+    right: 0;
+    left: auto;
+  }
+  .navbar-expand-sm .navbar-nav .nav-link {
+    padding-right: .5rem;
+    padding-left: .5rem;
+  }
+  .navbar-expand-sm > .container,
+  .navbar-expand-sm > .container-fluid {
+    -ms-flex-wrap: nowrap;
+        flex-wrap: nowrap;
+  }
+  .navbar-expand-sm .navbar-collapse {
+    display: -ms-flexbox !important;
+    display: flex !important;
+    -ms-flex-preferred-size: auto;
+        flex-basis: auto;
+  }
+  .navbar-expand-sm .navbar-toggler {
+    display: none;
+  }
+  .navbar-expand-sm .dropup .dropdown-menu {
+    top: auto;
+    bottom: 100%;
+  }
+}
+
+@media (max-width: 767px) {
+  .navbar-expand-md > .container,
+  .navbar-expand-md > .container-fluid {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+
+@media (min-width: 768px) {
+  .navbar-expand-md {
+    -ms-flex-flow: row nowrap;
+        flex-flow: row nowrap;
+    -ms-flex-pack: start;
+        justify-content: flex-start;
+  }
+  .navbar-expand-md .navbar-nav {
+    -ms-flex-direction: row;
+        flex-direction: row;
+  }
+  .navbar-expand-md .navbar-nav .dropdown-menu {
+    position: absolute;
+  }
+  .navbar-expand-md .navbar-nav .dropdown-menu-right {
+    right: 0;
+    left: auto;
+  }
+  .navbar-expand-md .navbar-nav .nav-link {
+    padding-right: .5rem;
+    padding-left: .5rem;
+  }
+  .navbar-expand-md > .container,
+  .navbar-expand-md > .container-fluid {
+    -ms-flex-wrap: nowrap;
+        flex-wrap: nowrap;
+  }
+  .navbar-expand-md .navbar-collapse {
+    display: -ms-flexbox !important;
+    display: flex !important;
+    -ms-flex-preferred-size: auto;
+        flex-basis: auto;
+  }
+  .navbar-expand-md .navbar-toggler {
+    display: none;
+  }
+  .navbar-expand-md .dropup .dropdown-menu {
+    top: auto;
+    bottom: 100%;
+  }
+}
+
+@media (max-width: 991px) {
+  .navbar-expand-lg > .container,
+  .navbar-expand-lg > .container-fluid {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+
+@media (min-width: 992px) {
+  .navbar-expand-lg {
+    -ms-flex-flow: row nowrap;
+        flex-flow: row nowrap;
+    -ms-flex-pack: start;
+        justify-content: flex-start;
+  }
+  .navbar-expand-lg .navbar-nav {
+    -ms-flex-direction: row;
+        flex-direction: row;
+  }
+  .navbar-expand-lg .navbar-nav .dropdown-menu {
+    position: absolute;
+  }
+  .navbar-expand-lg .navbar-nav .dropdown-menu-right {
+    right: 0;
+    left: auto;
+  }
+  .navbar-expand-lg .navbar-nav .nav-link {
+    padding-right: .5rem;
+    padding-left: .5rem;
+  }
+  .navbar-expand-lg > .container,
+  .navbar-expand-lg > .container-fluid {
+    -ms-flex-wrap: nowrap;
+        flex-wrap: nowrap;
+  }
+  .navbar-expand-lg .navbar-collapse {
+    display: -ms-flexbox !important;
+    display: flex !important;
+    -ms-flex-preferred-size: auto;
+        flex-basis: auto;
+  }
+  .navbar-expand-lg .navbar-toggler {
+    display: none;
+  }
+  .navbar-expand-lg .dropup .dropdown-menu {
+    top: auto;
+    bottom: 100%;
+  }
+}
+
+@media (max-width: 1199px) {
+  .navbar-expand-xl > .container,
+  .navbar-expand-xl > .container-fluid {
+    padding-right: 0;
+    padding-left: 0;
+  }
+}
+
+@media (min-width: 1200px) {
+  .navbar-expand-xl {
+    -ms-flex-flow: row nowrap;
+        flex-flow: row nowrap;
+    -ms-flex-pack: start;
+        justify-content: flex-start;
+  }
+  .navbar-expand-xl .navbar-nav {
+    -ms-flex-direction: row;
+        flex-direction: row;
+  }
+  .navbar-expand-xl .navbar-nav .dropdown-menu {
+    position: absolute;
+  }
+  .navbar-expand-xl .navbar-nav .dropdown-menu-right {
+    right: 0;
+    left: auto;
+  }
+  .navbar-expand-xl .navbar-nav .nav-link {
+    padding-right: .5rem;
+    padding-left: .5rem;
+  }
+  .navbar-expand-xl > .container,
+  .navbar-expand-xl > .container-fluid {
+    -ms-flex-wrap: nowrap;
+        flex-wrap: nowrap;
+  }
+  .navbar-expand-xl .navbar-collapse {
+    display: -ms-flexbox !important;
+    display: flex !important;
+    -ms-flex-preferred-size: auto;
+        flex-basis: auto;
+  }
+  .navbar-expand-xl .navbar-toggler {
+    display: none;
+  }
+  .navbar-expand-xl .dropup .dropdown-menu {
+    top: auto;
+    bottom: 100%;
+  }
+}
+
+.navbar-expand {
+  -ms-flex-flow: row nowrap;
+      flex-flow: row nowrap;
+  -ms-flex-pack: start;
+      justify-content: flex-start;
+}
+
+.navbar-expand > .container,
+.navbar-expand > .container-fluid {
+  padding-right: 0;
+  padding-left: 0;
+}
+
+.navbar-expand .navbar-nav {
+  -ms-flex-direction: row;
+      flex-direction: row;
+}
+
+.navbar-expand .navbar-nav .dropdown-menu {
+  position: absolute;
+}
+
+.navbar-expand .navbar-nav .dropdown-menu-right {
+  right: 0;
+  left: auto;
+}
+
+.navbar-expand .navbar-nav .nav-link {
+  padding-right: .5rem;
+  padding-left: .5rem;
+}
+
+.navbar-expand > .container,
+.navbar-expand > .container-fluid {
+  -ms-flex-wrap: nowrap;
+      flex-wrap: nowrap;
+}
+
+.navbar-expand .navbar-collapse {
+  display: -ms-flexbox !important;
+  display: flex !important;
+  -ms-flex-preferred-size: auto;
+      flex-basis: auto;
+}
+
+.navbar-expand .navbar-toggler {
+  display: none;
+}
+
+.navbar-expand .dropup .dropdown-menu {
+  top: auto;
+  bottom: 100%;
+}
+
+.navbar-light .navbar-brand {
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.navbar-light .navbar-brand:focus, .navbar-light .navbar-brand:hover {
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.navbar-light .navbar-nav .nav-link {
+  color: rgba(0, 0, 0, 0.5);
+}
+
+.navbar-light .navbar-nav .nav-link:focus, .navbar-light .navbar-nav .nav-link:hover {
+  color: rgba(0, 0, 0, 0.7);
+}
+
+.navbar-light .navbar-nav .nav-link.disabled {
+  color: rgba(0, 0, 0, 0.3);
+}
+
+.navbar-light .navbar-nav .show > .nav-link,
+.navbar-light .navbar-nav .active > .nav-link,
+.navbar-light .navbar-nav .nav-link.show,
+.navbar-light .navbar-nav .nav-link.active {
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.navbar-light .navbar-toggler {
+  color: rgba(0, 0, 0, 0.5);
+  border-color: rgba(0, 0, 0, 0.1);
+}
+
+.navbar-light .navbar-toggler-icon {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' 
xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' 
stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
+}
+
+.navbar-light .navbar-text {
+  color: rgba(0, 0, 0, 0.5);
+}
+
+.navbar-light .navbar-text a {
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.navbar-light .navbar-text a:focus, .navbar-light .navbar-text a:hover {
+  color: rgba(0, 0, 0, 0.9);
+}
+
+.navbar-dark .navbar-brand {
+  color: #fff;
+}
+
+.navbar-dark .navbar-brand:focus, .navbar-dark .navbar-brand:hover {
+  color: #fff;
+}
+
+.navbar-dark .navbar-nav .nav-link {
+  color: rgba(255, 255, 255, 0.5);
+}
+
+.navbar-dark .navbar-nav .nav-link:focus, .navbar-dark .navbar-nav .nav-link:hover {
+  color: rgba(255, 255, 255, 0.75);
+}
+
+.navbar-dark .navbar-nav .nav-link.disabled {
+  color: rgba(255, 255, 255, 0.25);
+}
+
+.navbar-dark .navbar-nav .show > .nav-link,
+.navbar-dark .navbar-nav .active > .nav-link,
+.navbar-dark .navbar-nav .nav-link.show,
+.navbar-dark .navbar-nav .nav-link.active {
+  color: #fff;
+}
+
+.navbar-dark .navbar-toggler {
+  color: rgba(255, 255, 255, 0.5);
+  border-color: rgba(255, 255, 255, 0.1);
+}
+
+.navbar-dark .navbar-toggler-icon {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' 
xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.5)' stroke-width='2' 
stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E");
+}
+
+.navbar-dark .navbar-text {
+  color: rgba(255, 255, 255, 0.5);
+}
+
+.navbar-dark .navbar-text a {
+  color: #fff;
+}
+
+.navbar-dark .navbar-text a:focus, .navbar-dark .navbar-text a:hover {
+  color: #fff;
+}
+
+.card {
+  position: relative;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+  min-width: 0;
+  word-wrap: break-word;
+  background-color: #fff;
+  background-clip: border-box;
+  border: 1px solid rgba(0, 0, 0, 0.125);
+  border-radius: 0.25rem;
+}
+
+.card > hr {
+  margin-right: 0;
+  margin-left: 0;
+}
+
+.card > .list-group:first-child .list-group-item:first-child {
+  border-top-left-radius: 0.25rem;
+  border-top-right-radius: 0.25rem;
+}
+
+.card > .list-group:last-child .list-group-item:last-child {
+  border-bottom-right-radius: 0.25rem;
+  border-bottom-left-radius: 0.25rem;
+}
+
+.card-body {
+  -ms-flex: 1 1 auto;
+      flex: 1 1 auto;
+  padding: 1.25rem;
+}
+
+.card-title {
+  margin-bottom: 0.75rem;
+}
+
+.card-subtitle {
+  margin-top: -0.375rem;
+  margin-bottom: 0;
+}
+
+.card-text:last-child {
+  margin-bottom: 0;
+}
+
+.card-link:hover {
+  text-decoration: none;
+}
+
+.card-link + .card-link {
+  margin-left: 1.25rem;
+}
+
+.card-header {
+  padding: 0.75rem 1.25rem;
+  margin-bottom: 0;
+  background-color: rgba(0, 0, 0, 0.03);
+  border-bottom: 1px solid rgba(0, 0, 0, 0.125);
+}
+
+.card-header:first-child {
+  border-radius: calc(0.25rem - 1px) calc(0.25rem - 1px) 0 0;
+}
+
+.card-header + .list-group .list-group-item:first-child {
+  border-top: 0;
+}
+
+.card-footer {
+  padding: 0.75rem 1.25rem;
+  background-color: rgba(0, 0, 0, 0.03);
+  border-top: 1px solid rgba(0, 0, 0, 0.125);
+}
+
+.card-footer:last-child {
+  border-radius: 0 0 calc(0.25rem - 1px) calc(0.25rem - 1px);
+}
+
+.card-header-tabs {
+  margin-right: -0.625rem;
+  margin-bottom: -0.75rem;
+  margin-left: -0.625rem;
+  border-bottom: 0;
+}
+
+.card-header-pills {
+  margin-right: -0.625rem;
+  margin-left: -0.625rem;
+}
+
+.card-img-overlay {
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  padding: 1.25rem;
+}
+
+.card-img {
+  width: 100%;
+  border-radius: calc(0.25rem - 1px);
+}
+
+.card-img-top {
+  width: 100%;
+  border-top-left-radius: calc(0.25rem - 1px);
+  border-top-right-radius: calc(0.25rem - 1px);
+}
+
+.card-img-bottom {
+  width: 100%;
+  border-bottom-right-radius: calc(0.25rem - 1px);
+  border-bottom-left-radius: calc(0.25rem - 1px);
+}
+
+.card-deck {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+}
+
+.card-deck .card {
+  margin-bottom: 15px;
+}
+
+@media (min-width: 576px) {
+  .card-deck {
+    -ms-flex-flow: row wrap;
+        flex-flow: row wrap;
+    margin-right: -15px;
+    margin-left: -15px;
+  }
+  .card-deck .card {
+    display: -ms-flexbox;
+    display: flex;
+    -ms-flex: 1 0 0%;
+        flex: 1 0 0%;
+    -ms-flex-direction: column;
+        flex-direction: column;
+    margin-right: 15px;
+    margin-bottom: 0;
+    margin-left: 15px;
+  }
+}
+
+.card-group {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+}
+
+.card-group .card {
+  margin-bottom: 15px;
+}
+
+@media (min-width: 576px) {
+  .card-group {
+    -ms-flex-flow: row wrap;
+        flex-flow: row wrap;
+  }
+  .card-group .card {
+    -ms-flex: 1 0 0%;
+        flex: 1 0 0%;
+    margin-bottom: 0;
+  }
+  .card-group .card + .card {
+    margin-left: 0;
+    border-left: 0;
+  }
+  .card-group .card:first-child {
+    border-top-right-radius: 0;
+    border-bottom-right-radius: 0;
+  }
+  .card-group .card:first-child .card-img-top {
+    border-top-right-radius: 0;
+  }
+  .card-group .card:first-child .card-img-bottom {
+    border-bottom-right-radius: 0;
+  }
+  .card-group .card:last-child {
+    border-top-left-radius: 0;
+    border-bottom-left-radius: 0;
+  }
+  .card-group .card:last-child .card-img-top {
+    border-top-left-radius: 0;
+  }
+  .card-group .card:last-child .card-img-bottom {
+    border-bottom-left-radius: 0;
+  }
+  .card-group .card:only-child {
+    border-radius: 0.25rem;
+  }
+  .card-group .card:only-child .card-img-top {
+    border-top-left-radius: 0.25rem;
+    border-top-right-radius: 0.25rem;
+  }
+  .card-group .card:only-child .card-img-bottom {
+    border-bottom-right-radius: 0.25rem;
+    border-bottom-left-radius: 0.25rem;
+  }
+  .card-group .card:not(:first-child):not(:last-child):not(:only-child) {
+    border-radius: 0;
+  }
+  .card-group .card:not(:first-child):not(:last-child):not(:only-child) .card-img-top,
+  .card-group .card:not(:first-child):not(:last-child):not(:only-child) .card-img-bottom {
+    border-radius: 0;
+  }
+}
+
+.card-columns .card {
+  margin-bottom: 0.75rem;
+}
+
+@media (min-width: 576px) {
+  .card-columns {
+    -webkit-column-count: 3;
+            column-count: 3;
+    -webkit-column-gap: 1.25rem;
+            column-gap: 1.25rem;
+  }
+  .card-columns .card {
+    display: inline-block;
+    width: 100%;
+  }
+}
+
+.breadcrumb {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-wrap: wrap;
+      flex-wrap: wrap;
+  padding: 0.75rem 1rem;
+  margin-bottom: 1rem;
+  list-style: none;
+  background-color: #e9ecef;
+  border-radius: 0.25rem;
+}
+
+.breadcrumb-item + .breadcrumb-item::before {
+  display: inline-block;
+  padding-right: 0.5rem;
+  padding-left: 0.5rem;
+  color: #868e96;
+  content: "/";
+}
+
+.breadcrumb-item + .breadcrumb-item:hover::before {
+  text-decoration: underline;
+}
+
+.breadcrumb-item + .breadcrumb-item:hover::before {
+  text-decoration: none;
+}
+
+.breadcrumb-item.active {
+  color: #868e96;
+}
+
+.pagination {
+  display: -ms-flexbox;
+  display: flex;
+  padding-left: 0;
+  list-style: none;
+  border-radius: 0.25rem;
+}
+
+.page-item:first-child .page-link {
+  margin-left: 0;
+  border-top-left-radius: 0.25rem;
+  border-bottom-left-radius: 0.25rem;
+}
+
+.page-item:last-child .page-link {
+  border-top-right-radius: 0.25rem;
+  border-bottom-right-radius: 0.25rem;
+}
+
+.page-item.active .page-link {
+  z-index: 2;
+  color: #fff;
+  background-color: #007bff;
+  border-color: #007bff;
+}
+
+.page-item.disabled .page-link {
+  color: #868e96;
+  pointer-events: none;
+  background-color: #fff;
+  border-color: #ddd;
+}
+
+.page-link {
+  position: relative;
+  display: block;
+  padding: 0.5rem 0.75rem;
+  margin-left: -1px;
+  line-height: 1.25;
+  color: #007bff;
+  background-color: #fff;
+  border: 1px solid #ddd;
+}
+
+.page-link:focus, .page-link:hover {
+  color: #0056b3;
+  text-decoration: none;
+  background-color: #e9ecef;
+  border-color: #ddd;
+}
+
+.pagination-lg .page-link {
+  padding: 0.75rem 1.5rem;
+  font-size: 1.25rem;
+  line-height: 1.5;
+}
+
+.pagination-lg .page-item:first-child .page-link {
+  border-top-left-radius: 0.3rem;
+  border-bottom-left-radius: 0.3rem;
+}
+
+.pagination-lg .page-item:last-child .page-link {
+  border-top-right-radius: 0.3rem;
+  border-bottom-right-radius: 0.3rem;
+}
+
+.pagination-sm .page-link {
+  padding: 0.25rem 0.5rem;
+  font-size: 0.875rem;
+  line-height: 1.5;
+}
+
+.pagination-sm .page-item:first-child .page-link {
+  border-top-left-radius: 0.2rem;
+  border-bottom-left-radius: 0.2rem;
+}
+
+.pagination-sm .page-item:last-child .page-link {
+  border-top-right-radius: 0.2rem;
+  border-bottom-right-radius: 0.2rem;
+}
+
+.badge {
+  display: inline-block;
+  padding: 0.25em 0.4em;
+  font-size: 75%;
+  font-weight: 700;
+  line-height: 1;
+  text-align: center;
+  white-space: nowrap;
+  vertical-align: baseline;
+  border-radius: 0.25rem;
+}
+
+.badge:empty {
+  display: none;
+}
+
+.btn .badge {
+  position: relative;
+  top: -1px;
+}
+
+.badge-pill {
+  padding-right: 0.6em;
+  padding-left: 0.6em;
+  border-radius: 10rem;
+}
+
+.badge-primary {
+  color: #fff;
+  background-color: #007bff;
+}
+
+.badge-primary[href]:focus, .badge-primary[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #0062cc;
+}
+
+.badge-secondary {
+  color: #fff;
+  background-color: #868e96;
+}
+
+.badge-secondary[href]:focus, .badge-secondary[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #6c757d;
+}
+
+.badge-success {
+  color: #fff;
+  background-color: #28a745;
+}
+
+.badge-success[href]:focus, .badge-success[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #1e7e34;
+}
+
+.badge-info {
+  color: #fff;
+  background-color: #17a2b8;
+}
+
+.badge-info[href]:focus, .badge-info[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #117a8b;
+}
+
+.badge-warning {
+  color: #111;
+  background-color: #ffc107;
+}
+
+.badge-warning[href]:focus, .badge-warning[href]:hover {
+  color: #111;
+  text-decoration: none;
+  background-color: #d39e00;
+}
+
+.badge-danger {
+  color: #fff;
+  background-color: #dc3545;
+}
+
+.badge-danger[href]:focus, .badge-danger[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #bd2130;
+}
+
+.badge-light {
+  color: #111;
+  background-color: #f8f9fa;
+}
+
+.badge-light[href]:focus, .badge-light[href]:hover {
+  color: #111;
+  text-decoration: none;
+  background-color: #dae0e5;
+}
+
+.badge-dark {
+  color: #fff;
+  background-color: #343a40;
+}
+
+.badge-dark[href]:focus, .badge-dark[href]:hover {
+  color: #fff;
+  text-decoration: none;
+  background-color: #1d2124;
+}
+
+.jumbotron {
+  padding: 2rem 1rem;
+  margin-bottom: 2rem;
+  background-color: #e9ecef;
+  border-radius: 0.3rem;
+}
+
+@media (min-width: 576px) {
+  .jumbotron {
+    padding: 4rem 2rem;
+  }
+}
+
+.jumbotron-fluid {
+  padding-right: 0;
+  padding-left: 0;
+  border-radius: 0;
+}
+
+.alert {
+  position: relative;
+  padding: 0.75rem 1.25rem;
+  margin-bottom: 1rem;
+  border: 1px solid transparent;
+  border-radius: 0.25rem;
+}
+
+.alert-heading {
+  color: inherit;
+}
+
+.alert-link {
+  font-weight: 700;
+}
+
+.alert-dismissible .close {
+  position: absolute;
+  top: 0;
+  right: 0;
+  padding: 0.75rem 1.25rem;
+  color: inherit;
+}
+
+.alert-primary {
+  color: #004085;
+  background-color: #cce5ff;
+  border-color: #b8daff;
+}
+
+.alert-primary hr {
+  border-top-color: #9fcdff;
+}
+
+.alert-primary .alert-link {
+  color: #002752;
+}
+
+.alert-secondary {
+  color: #464a4e;
+  background-color: #e7e8ea;
+  border-color: #dddfe2;
+}
+
+.alert-secondary hr {
+  border-top-color: #cfd2d6;
+}
+
+.alert-secondary .alert-link {
+  color: #2e3133;
+}
+
+.alert-success {
+  color: #155724;
+  background-color: #d4edda;
+  border-color: #c3e6cb;
+}
+
+.alert-success hr {
+  border-top-color: #b1dfbb;
+}
+
+.alert-success .alert-link {
+  color: #0b2e13;
+}
+
+.alert-info {
+  color: #0c5460;
+  background-color: #d1ecf1;
+  border-color: #bee5eb;
+}
+
+.alert-info hr {
+  border-top-color: #abdde5;
+}
+
+.alert-info .alert-link {
+  color: #062c33;
+}
+
+.alert-warning {
+  color: #856404;
+  background-color: #fff3cd;
+  border-color: #ffeeba;
+}
+
+.alert-warning hr {
+  border-top-color: #ffe8a1;
+}
+
+.alert-warning .alert-link {
+  color: #533f03;
+}
+
+.alert-danger {
+  color: #721c24;
+  background-color: #f8d7da;
+  border-color: #f5c6cb;
+}
+
+.alert-danger hr {
+  border-top-color: #f1b0b7;
+}
+
+.alert-danger .alert-link {
+  color: #491217;
+}
+
+.alert-light {
+  color: #818182;
+  background-color: #fefefe;
+  border-color: #fdfdfe;
+}
+
+.alert-light hr {
+  border-top-color: #ececf6;
+}
+
+.alert-light .alert-link {
+  color: #686868;
+}
+
+.alert-dark {
+  color: #1b1e21;
+  background-color: #d6d8d9;
+  border-color: #c6c8ca;
+}
+
+.alert-dark hr {
+  border-top-color: #b9bbbe;
+}
+
+.alert-dark .alert-link {
+  color: #040505;
+}
+
+@-webkit-keyframes progress-bar-stripes {
+  from {
+    background-position: 1rem 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+
+@keyframes progress-bar-stripes {
+  from {
+    background-position: 1rem 0;
+  }
+  to {
+    background-position: 0 0;
+  }
+}
+
+.progress {
+  display: -ms-flexbox;
+  display: flex;
+  height: 1rem;
+  overflow: hidden;
+  font-size: 0.75rem;
+  background-color: #e9ecef;
+  border-radius: 0.25rem;
+}
+
+.progress-bar {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: center;
+      align-items: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  color: #fff;
+  background-color: #007bff;
+}
+
+.progress-bar-striped {
+  background-image: linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, 
rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);
+  background-size: 1rem 1rem;
+}
+
+.progress-bar-animated {
+  -webkit-animation: progress-bar-stripes 1s linear infinite;
+          animation: progress-bar-stripes 1s linear infinite;
+}
+
+.media {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: start;
+      align-items: flex-start;
+}
+
+.media-body {
+  -ms-flex: 1;
+      flex: 1;
+}
+
+.list-group {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+  padding-left: 0;
+  margin-bottom: 0;
+}
+
+.list-group-item-action {
+  width: 100%;
+  color: #495057;
+  text-align: inherit;
+}
+
+.list-group-item-action:focus, .list-group-item-action:hover {
+  color: #495057;
+  text-decoration: none;
+  background-color: #f8f9fa;
+}
+
+.list-group-item-action:active {
+  color: #212529;
+  background-color: #e9ecef;
+}
+
+.list-group-item {
+  position: relative;
+  display: block;
+  padding: 0.75rem 1.25rem;
+  margin-bottom: -1px;
+  background-color: #fff;
+  border: 1px solid rgba(0, 0, 0, 0.125);
+}
+
+.list-group-item:first-child {
+  border-top-left-radius: 0.25rem;
+  border-top-right-radius: 0.25rem;
+}
+
+.list-group-item:last-child {
+  margin-bottom: 0;
+  border-bottom-right-radius: 0.25rem;
+  border-bottom-left-radius: 0.25rem;
+}
+
+.list-group-item:focus, .list-group-item:hover {
+  text-decoration: none;
+}
+
+.list-group-item.disabled, .list-group-item:disabled {
+  color: #868e96;
+  background-color: #fff;
+}
+
+.list-group-item.active {
+  z-index: 2;
+  color: #fff;
+  background-color: #007bff;
+  border-color: #007bff;
+}
+
+.list-group-flush .list-group-item {
+  border-right: 0;
+  border-left: 0;
+  border-radius: 0;
+}
+
+.list-group-flush:first-child .list-group-item:first-child {
+  border-top: 0;
+}
+
+.list-group-flush:last-child .list-group-item:last-child {
+  border-bottom: 0;
+}
+
+.list-group-item-primary {
+  color: #004085;
+  background-color: #b8daff;
+}
+
+a.list-group-item-primary,
+button.list-group-item-primary {
+  color: #004085;
+}
+
+a.list-group-item-primary:focus, a.list-group-item-primary:hover,
+button.list-group-item-primary:focus,
+button.list-group-item-primary:hover {
+  color: #004085;
+  background-color: #9fcdff;
+}
+
+a.list-group-item-primary.active,
+button.list-group-item-primary.active {
+  color: #fff;
+  background-color: #004085;
+  border-color: #004085;
+}
+
+.list-group-item-secondary {
+  color: #464a4e;
+  background-color: #dddfe2;
+}
+
+a.list-group-item-secondary,
+button.list-group-item-secondary {
+  color: #464a4e;
+}
+
+a.list-group-item-secondary:focus, a.list-group-item-secondary:hover,
+button.list-group-item-secondary:focus,
+button.list-group-item-secondary:hover {
+  color: #464a4e;
+  background-color: #cfd2d6;
+}
+
+a.list-group-item-secondary.active,
+button.list-group-item-secondary.active {
+  color: #fff;
+  background-color: #464a4e;
+  border-color: #464a4e;
+}
+
+.list-group-item-success {
+  color: #155724;
+  background-color: #c3e6cb;
+}
+
+a.list-group-item-success,
+button.list-group-item-success {
+  color: #155724;
+}
+
+a.list-group-item-success:focus, a.list-group-item-success:hover,
+button.list-group-item-success:focus,
+button.list-group-item-success:hover {
+  color: #155724;
+  background-color: #b1dfbb;
+}
+
+a.list-group-item-success.active,
+button.list-group-item-success.active {
+  color: #fff;
+  background-color: #155724;
+  border-color: #155724;
+}
+
+.list-group-item-info {
+  color: #0c5460;
+  background-color: #bee5eb;
+}
+
+a.list-group-item-info,
+button.list-group-item-info {
+  color: #0c5460;
+}
+
+a.list-group-item-info:focus, a.list-group-item-info:hover,
+button.list-group-item-info:focus,
+button.list-group-item-info:hover {
+  color: #0c5460;
+  background-color: #abdde5;
+}
+
+a.list-group-item-info.active,
+button.list-group-item-info.active {
+  color: #fff;
+  background-color: #0c5460;
+  border-color: #0c5460;
+}
+
+.list-group-item-warning {
+  color: #856404;
+  background-color: #ffeeba;
+}
+
+a.list-group-item-warning,
+button.list-group-item-warning {
+  color: #856404;
+}
+
+a.list-group-item-warning:focus, a.list-group-item-warning:hover,
+button.list-group-item-warning:focus,
+button.list-group-item-warning:hover {
+  color: #856404;
+  background-color: #ffe8a1;
+}
+
+a.list-group-item-warning.active,
+button.list-group-item-warning.active {
+  color: #fff;
+  background-color: #856404;
+  border-color: #856404;
+}
+
+.list-group-item-danger {
+  color: #721c24;
+  background-color: #f5c6cb;
+}
+
+a.list-group-item-danger,
+button.list-group-item-danger {
+  color: #721c24;
+}
+
+a.list-group-item-danger:focus, a.list-group-item-danger:hover,
+button.list-group-item-danger:focus,
+button.list-group-item-danger:hover {
+  color: #721c24;
+  background-color: #f1b0b7;
+}
+
+a.list-group-item-danger.active,
+button.list-group-item-danger.active {
+  color: #fff;
+  background-color: #721c24;
+  border-color: #721c24;
+}
+
+.list-group-item-light {
+  color: #818182;
+  background-color: #fdfdfe;
+}
+
+a.list-group-item-light,
+button.list-group-item-light {
+  color: #818182;
+}
+
+a.list-group-item-light:focus, a.list-group-item-light:hover,
+button.list-group-item-light:focus,
+button.list-group-item-light:hover {
+  color: #818182;
+  background-color: #ececf6;
+}
+
+a.list-group-item-light.active,
+button.list-group-item-light.active {
+  color: #fff;
+  background-color: #818182;
+  border-color: #818182;
+}
+
+.list-group-item-dark {
+  color: #1b1e21;
+  background-color: #c6c8ca;
+}
+
+a.list-group-item-dark,
+button.list-group-item-dark {
+  color: #1b1e21;
+}
+
+a.list-group-item-dark:focus, a.list-group-item-dark:hover,
+button.list-group-item-dark:focus,
+button.list-group-item-dark:hover {
+  color: #1b1e21;
+  background-color: #b9bbbe;
+}
+
+a.list-group-item-dark.active,
+button.list-group-item-dark.active {
+  color: #fff;
+  background-color: #1b1e21;
+  border-color: #1b1e21;
+}
+
+.close {
+  float: right;
+  font-size: 1.5rem;
+  font-weight: 700;
+  line-height: 1;
+  color: #000;
+  text-shadow: 0 1px 0 #fff;
+  opacity: .5;
+}
+
+.close:focus, .close:hover {
+  color: #000;
+  text-decoration: none;
+  opacity: .75;
+}
+
+button.close {
+  padding: 0;
+  background: transparent;
+  border: 0;
+  -webkit-appearance: none;
+}
+
+.modal-open {
+  overflow: hidden;
+}
+
+.modal {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1050;
+  display: none;
+  overflow: hidden;
+  outline: 0;
+}
+
+.modal.fade .modal-dialog {
+  transition: -webkit-transform 0.3s ease-out;
+  transition: transform 0.3s ease-out;
+  transition: transform 0.3s ease-out, -webkit-transform 0.3s ease-out;
+  -webkit-transform: translate(0, -25%);
+          transform: translate(0, -25%);
+}
+
+.modal.show .modal-dialog {
+  -webkit-transform: translate(0, 0);
+          transform: translate(0, 0);
+}
+
+.modal-open .modal {
+  overflow-x: hidden;
+  overflow-y: auto;
+}
+
+.modal-dialog {
+  position: relative;
+  width: auto;
+  margin: 10px;
+  pointer-events: none;
+}
+
+.modal-content {
+  position: relative;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-direction: column;
+      flex-direction: column;
+  pointer-events: auto;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 0.3rem;
+  outline: 0;
+}
+
+.modal-backdrop {
+  position: fixed;
+  top: 0;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1040;
+  background-color: #000;
+}
+
+.modal-backdrop.fade {
+  opacity: 0;
+}
+
+.modal-backdrop.show {
+  opacity: 0.5;
+}
+
+.modal-header {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: start;
+      align-items: flex-start;
+  -ms-flex-pack: justify;
+      justify-content: space-between;
+  padding: 15px;
+  border-bottom: 1px solid #e9ecef;
+  border-top-left-radius: 0.3rem;
+  border-top-right-radius: 0.3rem;
+}
+
+.modal-header .close {
+  padding: 15px;
+  margin: -15px -15px -15px auto;
+}
+
+.modal-title {
+  margin-bottom: 0;
+  line-height: 1.5;
+}
+
+.modal-body {
+  position: relative;
+  -ms-flex: 1 1 auto;
+      flex: 1 1 auto;
+  padding: 15px;
+}
+
+.modal-footer {
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: center;
+      align-items: center;
+  -ms-flex-pack: end;
+      justify-content: flex-end;
+  padding: 15px;
+  border-top: 1px solid #e9ecef;
+}
+
+.modal-footer > :not(:first-child) {
+  margin-left: .25rem;
+}
+
+.modal-footer > :not(:last-child) {
+  margin-right: .25rem;
+}
+
+.modal-scrollbar-measure {
+  position: absolute;
+  top: -9999px;
+  width: 50px;
+  height: 50px;
+  overflow: scroll;
+}
+
+@media (min-width: 576px) {
+  .modal-dialog {
+    max-width: 500px;
+    margin: 30px auto;
+  }
+  .modal-sm {
+    max-width: 300px;
+  }
+}
+
+@media (min-width: 992px) {
+  .modal-lg {
+    max-width: 800px;
+  }
+}
+
+.tooltip {
+  position: absolute;
+  z-index: 1070;
+  display: block;
+  margin: 0;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, 
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  font-style: normal;
+  font-weight: 400;
+  line-height: 1.5;
+  text-align: left;
+  text-align: start;
+  text-decoration: none;
+  text-shadow: none;
+  text-transform: none;
+  letter-spacing: normal;
+  word-break: normal;
+  word-spacing: normal;
+  white-space: normal;
+  line-break: auto;
+  font-size: 0.875rem;
+  word-wrap: break-word;
+  opacity: 0;
+}
+
+.tooltip.show {
+  opacity: 0.9;
+}
+
+.tooltip .arrow {
+  position: absolute;
+  display: block;
+  width: 5px;
+  height: 5px;
+}
+
+.tooltip .arrow::before {
+  position: absolute;
+  border-color: transparent;
+  border-style: solid;
+}
+
+.tooltip.bs-tooltip-top, .tooltip.bs-tooltip-auto[x-placement^="top"] {
+  padding: 5px 0;
+}
+
+.tooltip.bs-tooltip-top .arrow, .tooltip.bs-tooltip-auto[x-placement^="top"] .arrow {
+  bottom: 0;
+}
+
+.tooltip.bs-tooltip-top .arrow::before, .tooltip.bs-tooltip-auto[x-placement^="top"] .arrow::before {
+  margin-left: -3px;
+  content: "";
+  border-width: 5px 5px 0;
+  border-top-color: #000;
+}
+
+.tooltip.bs-tooltip-right, .tooltip.bs-tooltip-auto[x-placement^="right"] {
+  padding: 0 5px;
+}
+
+.tooltip.bs-tooltip-right .arrow, .tooltip.bs-tooltip-auto[x-placement^="right"] .arrow {
+  left: 0;
+}
+
+.tooltip.bs-tooltip-right .arrow::before, .tooltip.bs-tooltip-auto[x-placement^="right"] .arrow::before {
+  margin-top: -3px;
+  content: "";
+  border-width: 5px 5px 5px 0;
+  border-right-color: #000;
+}
+
+.tooltip.bs-tooltip-bottom, .tooltip.bs-tooltip-auto[x-placement^="bottom"] {
+  padding: 5px 0;
+}
+
+.tooltip.bs-tooltip-bottom .arrow, .tooltip.bs-tooltip-auto[x-placement^="bottom"] .arrow {
+  top: 0;
+}
+
+.tooltip.bs-tooltip-bottom .arrow::before, .tooltip.bs-tooltip-auto[x-placement^="bottom"] .arrow::before {
+  margin-left: -3px;
+  content: "";
+  border-width: 0 5px 5px;
+  border-bottom-color: #000;
+}
+
+.tooltip.bs-tooltip-left, .tooltip.bs-tooltip-auto[x-placement^="left"] {
+  padding: 0 5px;
+}
+
+.tooltip.bs-tooltip-left .arrow, .tooltip.bs-tooltip-auto[x-placement^="left"] .arrow {
+  right: 0;
+}
+
+.tooltip.bs-tooltip-left .arrow::before, .tooltip.bs-tooltip-auto[x-placement^="left"] .arrow::before {
+  right: 0;
+  margin-top: -3px;
+  content: "";
+  border-width: 5px 0 5px 5px;
+  border-left-color: #000;
+}
+
+.tooltip-inner {
+  max-width: 200px;
+  padding: 3px 8px;
+  color: #fff;
+  text-align: center;
+  background-color: #000;
+  border-radius: 0.25rem;
+}
+
+.popover {
+  position: absolute;
+  top: 0;
+  left: 0;
+  z-index: 1060;
+  display: block;
+  max-width: 276px;
+  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif, 
"Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
+  font-style: normal;
+  font-weight: 400;
+  line-height: 1.5;
+  text-align: left;
+  text-align: start;
+  text-decoration: none;
+  text-shadow: none;
+  text-transform: none;
+  letter-spacing: normal;
+  word-break: normal;
+  word-spacing: normal;
+  white-space: normal;
+  line-break: auto;
+  font-size: 0.875rem;
+  word-wrap: break-word;
+  background-color: #fff;
+  background-clip: padding-box;
+  border: 1px solid rgba(0, 0, 0, 0.2);
+  border-radius: 0.3rem;
+}
+
+.popover .arrow {
+  position: absolute;
+  display: block;
+  width: 0.8rem;
+  height: 0.4rem;
+}
+
+.popover .arrow::before,
+.popover .arrow::after {
+  position: absolute;
+  display: block;
+  border-color: transparent;
+  border-style: solid;
+}
+
+.popover .arrow::before {
+  content: "";
+  border-width: 0.8rem;
+}
+
+.popover .arrow::after {
+  content: "";
+  border-width: 0.8rem;
+}
+
+.popover.bs-popover-top, .popover.bs-popover-auto[x-placement^="top"] {
+  margin-bottom: 0.8rem;
+}
+
+.popover.bs-popover-top .arrow, .popover.bs-popover-auto[x-placement^="top"] .arrow {
+  bottom: 0;
+}
+
+.popover.bs-popover-top .arrow::before, .popover.bs-popover-auto[x-placement^="top"] .arrow::before,
+.popover.bs-popover-top .arrow::after, .popover.bs-popover-auto[x-placement^="top"] .arrow::after {
+  border-bottom-width: 0;
+}
+
+.popover.bs-popover-top .arrow::before, .popover.bs-popover-auto[x-placement^="top"] .arrow::before {
+  bottom: -0.8rem;
+  margin-left: -0.8rem;
+  border-top-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.bs-popover-top .arrow::after, .popover.bs-popover-auto[x-placement^="top"] .arrow::after {
+  bottom: calc((0.8rem - 1px) * -1);
+  margin-left: -0.8rem;
+  border-top-color: #fff;
+}
+
+.popover.bs-popover-right, .popover.bs-popover-auto[x-placement^="right"] {
+  margin-left: 0.8rem;
+}
+
+.popover.bs-popover-right .arrow, .popover.bs-popover-auto[x-placement^="right"] .arrow {
+  left: 0;
+}
+
+.popover.bs-popover-right .arrow::before, .popover.bs-popover-auto[x-placement^="right"] .arrow::before,
+.popover.bs-popover-right .arrow::after, .popover.bs-popover-auto[x-placement^="right"] .arrow::after {
+  margin-top: -0.8rem;
+  border-left-width: 0;
+}
+
+.popover.bs-popover-right .arrow::before, .popover.bs-popover-auto[x-placement^="right"] .arrow::before {
+  left: -0.8rem;
+  border-right-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.bs-popover-right .arrow::after, .popover.bs-popover-auto[x-placement^="right"] .arrow::after {
+  left: calc((0.8rem - 1px) * -1);
+  border-right-color: #fff;
+}
+
+.popover.bs-popover-bottom, .popover.bs-popover-auto[x-placement^="bottom"] {
+  margin-top: 0.8rem;
+}
+
+.popover.bs-popover-bottom .arrow, .popover.bs-popover-auto[x-placement^="bottom"] .arrow {
+  top: 0;
+}
+
+.popover.bs-popover-bottom .arrow::before, .popover.bs-popover-auto[x-placement^="bottom"] .arrow::before,
+.popover.bs-popover-bottom .arrow::after, .popover.bs-popover-auto[x-placement^="bottom"] .arrow::after {
+  margin-left: -0.8rem;
+  border-top-width: 0;
+}
+
+.popover.bs-popover-bottom .arrow::before, .popover.bs-popover-auto[x-placement^="bottom"] .arrow::before {
+  top: -0.8rem;
+  border-bottom-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.bs-popover-bottom .arrow::after, .popover.bs-popover-auto[x-placement^="bottom"] .arrow::after {
+  top: calc((0.8rem - 1px) * -1);
+  border-bottom-color: #fff;
+}
+
+.popover.bs-popover-bottom .popover-header::before, .popover.bs-popover-auto[x-placement^="bottom"] 
.popover-header::before {
+  position: absolute;
+  top: 0;
+  left: 50%;
+  display: block;
+  width: 20px;
+  margin-left: -10px;
+  content: "";
+  border-bottom: 1px solid #f7f7f7;
+}
+
+.popover.bs-popover-left, .popover.bs-popover-auto[x-placement^="left"] {
+  margin-right: 0.8rem;
+}
+
+.popover.bs-popover-left .arrow, .popover.bs-popover-auto[x-placement^="left"] .arrow {
+  right: 0;
+}
+
+.popover.bs-popover-left .arrow::before, .popover.bs-popover-auto[x-placement^="left"] .arrow::before,
+.popover.bs-popover-left .arrow::after, .popover.bs-popover-auto[x-placement^="left"] .arrow::after {
+  margin-top: -0.8rem;
+  border-right-width: 0;
+}
+
+.popover.bs-popover-left .arrow::before, .popover.bs-popover-auto[x-placement^="left"] .arrow::before {
+  right: -0.8rem;
+  border-left-color: rgba(0, 0, 0, 0.25);
+}
+
+.popover.bs-popover-left .arrow::after, .popover.bs-popover-auto[x-placement^="left"] .arrow::after {
+  right: calc((0.8rem - 1px) * -1);
+  border-left-color: #fff;
+}
+
+.popover-header {
+  padding: 0.5rem 0.75rem;
+  margin-bottom: 0;
+  font-size: 1rem;
+  color: inherit;
+  background-color: #f7f7f7;
+  border-bottom: 1px solid #ebebeb;
+  border-top-left-radius: calc(0.3rem - 1px);
+  border-top-right-radius: calc(0.3rem - 1px);
+}
+
+.popover-header:empty {
+  display: none;
+}
+
+.popover-body {
+  padding: 0.5rem 0.75rem;
+  color: #212529;
+}
+
+.carousel {
+  position: relative;
+}
+
+.carousel-inner {
+  position: relative;
+  width: 100%;
+  overflow: hidden;
+}
+
+.carousel-item {
+  position: relative;
+  display: none;
+  -ms-flex-align: center;
+      align-items: center;
+  width: 100%;
+  transition: -webkit-transform 0.6s ease;
+  transition: transform 0.6s ease;
+  transition: transform 0.6s ease, -webkit-transform 0.6s ease;
+  -webkit-backface-visibility: hidden;
+          backface-visibility: hidden;
+  -webkit-perspective: 1000px;
+          perspective: 1000px;
+}
+
+.carousel-item.active,
+.carousel-item-next,
+.carousel-item-prev {
+  display: block;
+}
+
+.carousel-item-next,
+.carousel-item-prev {
+  position: absolute;
+  top: 0;
+}
+
+.carousel-item-next.carousel-item-left,
+.carousel-item-prev.carousel-item-right {
+  -webkit-transform: translateX(0);
+          transform: translateX(0);
+}
+
+@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {
+  .carousel-item-next.carousel-item-left,
+  .carousel-item-prev.carousel-item-right {
+    -webkit-transform: translate3d(0, 0, 0);
+            transform: translate3d(0, 0, 0);
+  }
+}
+
+.carousel-item-next,
+.active.carousel-item-right {
+  -webkit-transform: translateX(100%);
+          transform: translateX(100%);
+}
+
+@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {
+  .carousel-item-next,
+  .active.carousel-item-right {
+    -webkit-transform: translate3d(100%, 0, 0);
+            transform: translate3d(100%, 0, 0);
+  }
+}
+
+.carousel-item-prev,
+.active.carousel-item-left {
+  -webkit-transform: translateX(-100%);
+          transform: translateX(-100%);
+}
+
+@supports ((-webkit-transform-style: preserve-3d) or (transform-style: preserve-3d)) {
+  .carousel-item-prev,
+  .active.carousel-item-left {
+    -webkit-transform: translate3d(-100%, 0, 0);
+            transform: translate3d(-100%, 0, 0);
+  }
+}
+
+.carousel-control-prev,
+.carousel-control-next {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-align: center;
+      align-items: center;
+  -ms-flex-pack: center;
+      justify-content: center;
+  width: 15%;
+  color: #fff;
+  text-align: center;
+  opacity: 0.5;
+}
+
+.carousel-control-prev:focus, .carousel-control-prev:hover,
+.carousel-control-next:focus,
+.carousel-control-next:hover {
+  color: #fff;
+  text-decoration: none;
+  outline: 0;
+  opacity: .9;
+}
+
+.carousel-control-prev {
+  left: 0;
+}
+
+.carousel-control-next {
+  right: 0;
+}
+
+.carousel-control-prev-icon,
+.carousel-control-next-icon {
+  display: inline-block;
+  width: 20px;
+  height: 20px;
+  background: transparent no-repeat center center;
+  background-size: 100% 100%;
+}
+
+.carousel-control-prev-icon {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 
fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 
2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E");
+}
+
+.carousel-control-next-icon {
+  background-image: url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' 
fill='%23fff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 
4-4-4-4z'/%3E%3C/svg%3E");
+}
+
+.carousel-indicators {
+  position: absolute;
+  right: 0;
+  bottom: 10px;
+  left: 0;
+  z-index: 15;
+  display: -ms-flexbox;
+  display: flex;
+  -ms-flex-pack: center;
+      justify-content: center;
+  padding-left: 0;
+  margin-right: 15%;
+  margin-left: 15%;
+  list-style: none;
+}
+
+.carousel-indicators li {
+  position: relative;
+  -ms-flex: 0 1 auto;
+      flex: 0 1 auto;
+  width: 30px;
+  height: 3px;
+  margin-right: 3px;
+  margin-left: 3px;
+  text-indent: -999px;
+  background-color: rgba(255, 255, 255, 0.5);
+}
+
+.carousel-indicators li::before {
+  position: absolute;
+  top: -10px;
+  left: 0;
+  display: inline-block;
+  width: 100%;
+  height: 10px;
+  content: "";
+}
+
+.carousel-indicators li::after {
+  position: absolute;
+  bottom: -10px;
+  left: 0;
+  display: inline-block;
+  width: 100%;
+  height: 10px;
+  content: "";
+}
+
+.carousel-indicators .active {
+  background-color: #fff;
+}
+
+.carousel-caption {
+  position: absolute;
+  right: 15%;
+  bottom: 20px;
+  left: 15%;
+  z-index: 10;
+  padding-top: 20px;
+  padding-bottom: 20px;
+  color: #fff;
+  text-align: center;
+}
+
+.align-baseline {
+  vertical-align: baseline !important;
+}
+
+.align-top {
+  vertical-align: top !important;
+}
+
+.align-middle {
+  vertical-align: middle !important;
+}
+
+.align-bottom {
+  vertical-align: bottom !important;
+}
+
+.align-text-bottom {
+  vertical-align: text-bottom !important;
+}
+
+.align-text-top {
+  vertical-align: text-top !important;
+}
+
+.bg-primary {
+  background-color: #007bff !important;
+}
+
+a.bg-primary:focus, a.bg-primary:hover {
+  background-color: #0062cc !important;
+}
+
+.bg-secondary {
+  background-color: #868e96 !important;
+}
+
+a.bg-secondary:focus, a.bg-secondary:hover {
+  background-color: #6c757d !important;
+}
+
+.bg-success {
+  background-color: #28a745 !important;
+}
+
+a.bg-success:focus, a.bg-success:hover {
+  background-color: #1e7e34 !important;
+}
+
+.bg-info {
+  background-color: #17a2b8 !important;
+}
+
+a.bg-info:focus, a.bg-info:hover {
+  background-color: #117a8b !important;
+}
+
+.bg-warning {
+  background-color: #ffc107 !important;
+}
+
+a.bg-warning:focus, a.bg-warning:hover {
+  background-color: #d39e00 !important;
+}
+
+.bg-danger {
+  background-color: #dc3545 !important;
+}
+
+a.bg-danger:focus, a.bg-danger:hover {
+  background-color: #bd2130 !important;
+}
+
+.bg-light {
+  background-color: #f8f9fa !important;
+}
+
+a.bg-light:focus, a.bg-light:hover {
+  background-color: #dae0e5 !important;
+}
+
+.bg-dark {
+  background-color: #343a40 !important;
+}
+
+a.bg-dark:focus, a.bg-dark:hover {
+  background-color: #1d2124 !important;
+}
+
+.bg-white {
+  background-color: #fff !important;
+}
+
+.bg-transparent {
+  background-color: transparent !important;
+}
+
+.border {
+  border: 1px solid #e9ecef !important;
+}
+
+.border-0 {
+  border: 0 !important;
+}
+
+.border-top-0 {
+  border-top: 0 !important;
+}
+
+.border-right-0 {
+  border-right: 0 !important;
+}
+
+.border-bottom-0 {
+  border-bottom: 0 !important;
+}
+
+.border-left-0 {
+  border-left: 0 !important;
+}
+
+.border-primary {
+  border-color: #007bff !important;
+}
+
+.border-secondary {
+  border-color: #868e96 !important;
+}
+
+.border-success {
+  border-color: #28a745 !important;
+}
+
+.border-info {
+  border-color: #17a2b8 !important;
+}
+
+.border-warning {
+  border-color: #ffc107 !important;
+}
+
+.border-danger {
+  border-color: #dc3545 !important;
+}
+
+.border-light {
+  border-color: #f8f9fa !important;
+}
+
+.border-dark {
+  border-color: #343a40 !important;
+}
+
+.border-white {
+  border-color: #fff !important;
+}
+
+.rounded {
+  border-radius: 0.25rem !important;
+}
+
+.rounded-top {
+  border-top-left-radius: 0.25rem !important;
+  border-top-right-radius: 0.25rem !important;
+}
+
+.rounded-right {
+  border-top-right-radius: 0.25rem !important;
+  border-bottom-right-radius: 0.25rem !important;
+}
+
+.rounded-bottom {
+  border-bottom-right-radius: 0.25rem !important;
+  border-bottom-left-radius: 0.25rem !important;
+}
+
+.rounded-left {
+  border-top-left-radius: 0.25rem !important;
+  border-bottom-left-radius: 0.25rem !important;
+}
+
+.rounded-circle {
+  border-radius: 50% !important;
+}
+
+.rounded-0 {
+  border-radius: 0 !important;
+}
+
+.clearfix::after {
+  display: block;
+  clear: both;
+  content: "";
+}
+
+.d-none {
+  display: none !important;
+}
+
+.d-inline {
+  display: inline !important;
+}
+
+.d-inline-block {
+  display: inline-block !important;
+}
+
+.d-block {
+  display: block !important;
+}
+
+.d-table {
+  display: table !important;
+}
+
+.d-table-row {
+  display: table-row !important;
+}
+
+.d-table-cell {
+  display: table-cell !important;
+}
+
+.d-flex {
+  display: -ms-flexbox !important;
+  display: flex !important;
+}
+
+.d-inline-flex {
+  display: -ms-inline-flexbox !important;
+  display: inline-flex !important;
+}
+
+@media (min-width: 576px) {
+  .d-sm-none {
+    display: none !important;
+  }
+  .d-sm-inline {
+    display: inline !important;
+  }
+  .d-sm-inline-block {
+    display: inline-block !important;
+  }
+  .d-sm-block {
+    display: block !important;
+  }
+  .d-sm-table {
+    display: table !important;
+  }
+  .d-sm-table-row {
+    display: table-row !important;
+  }
+  .d-sm-table-cell {
+    display: table-cell !important;
+  }
+  .d-sm-flex {
+    display: -ms-flexbox !important;
+    display: flex !important;
+  }
+  .d-sm-inline-flex {
+    display: -ms-inline-flexbox !important;
+    display: inline-flex !important;
+  }
+}
+
+@media (min-width: 768px) {
+  .d-md-none {
+    display: none !important;
+  }
+  .d-md-inline {
+    display: inline !important;
+  }
+  .d-md-inline-block {
+    display: inline-block !important;
+  }
+  .d-md-block {
+    display: block !important;
+  }
+  .d-md-table {
+    display: table !important;
+  }
+  .d-md-table-row {
+    display: table-row !important;
+  }
+  .d-md-table-cell {
+    display: table-cell !important;
+  }
+  .d-md-flex {
+    display: -ms-flexbox !important;
+    display: flex !important;
+  }
+  .d-md-inline-flex {
+    display: -ms-inline-flexbox !important;
+    display: inline-flex !important;
+  }
+}
+
+@media (min-width: 992px) {
+  .d-lg-none {
+    display: none !important;
+  }
+  .d-lg-inline {
+    display: inline !important;
+  }
+  .d-lg-inline-block {
+    display: inline-block !important;
+  }
+  .d-lg-block {
+    display: block !important;
+  }
+  .d-lg-table {
+    display: table !important;
+  }
+  .d-lg-table-row {
+    display: table-row !important;
+  }
+  .d-lg-table-cell {
+    display: table-cell !important;
+  }
+  .d-lg-flex {
+    display: -ms-flexbox !important;
+    display: flex !important;
+  }
+  .d-lg-inline-flex {
+    display: -ms-inline-flexbox !important;
+    display: inline-flex !important;
+  }
+}
+
+@media (min-width: 1200px) {
+  .d-xl-none {
+    display: none !important;
+  }
+  .d-xl-inline {
+    display: inline !important;
+  }
+  .d-xl-inline-block {
+    display: inline-block !important;
+  }
+  .d-xl-block {
+    display: block !important;
+  }
+  .d-xl-table {
+    display: table !important;
+  }
+  .d-xl-table-row {
+    display: table-row !important;
+  }
+  .d-xl-table-cell {
+    display: table-cell !important;
+  }
+  .d-xl-flex {
+    display: -ms-flexbox !important;
+    display: flex !important;
+  }
+  .d-xl-inline-flex {
+    display: -ms-inline-flexbox !important;
+    display: inline-flex !important;
+  }
+}
+
+.d-print-block {
+  display: none !important;
+}
+
+@media print {
+  .d-print-block {
+    display: block !important;
+  }
+}
+
+.d-print-inline {
+  display: none !important;
+}
+
+@media print {
+  .d-print-inline {
+    display: inline !important;
+  }
+}
+
+.d-print-inline-block {
+  display: none !important;
+}
+
+@media print {
+  .d-print-inline-block {
+    display: inline-block !important;
+  }
+}
+
+@media print {
+  .d-print-none {
+    display: none !important;
+  }
+}
+
+.embed-responsive {
+  position: relative;
+  display: block;
+  width: 100%;
+  padding: 0;
+  overflow: hidden;
+}
+
+.embed-responsive::before {
+  display: block;
+  content: "";
+}
+
+.embed-responsive .embed-responsive-item,
+.embed-responsive iframe,
+.embed-responsive embed,
+.embed-responsive object,
+.embed-responsive video {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  left: 0;
+  width: 100%;
+  height: 100%;
+  border: 0;
+}
+
+.embed-responsive-21by9::before {
+  padding-top: 42.857143%;
+}
+
+.embed-responsive-16by9::before {
+  padding-top: 56.25%;
+}
+
+.embed-responsive-4by3::before {
+  padding-top: 75%;
+}
+
+.embed-responsive-1by1::before {
+  padding-top: 100%;
+}
+
+.flex-row {
+  -ms-flex-direction: row !important;
+      flex-direction: row !important;
+}
+
+.flex-column {
+  -ms-flex-direction: column !important;
+      flex-direction: column !important;
+}
+
+.flex-row-reverse {
+  -ms-flex-direction: row-reverse !important;
+      flex-direction: row-reverse !important;
+}
+
+.flex-column-reverse {
+  -ms-flex-direction: column-reverse !important;
+      flex-direction: column-reverse !important;
+}
+
+.flex-wrap {
+  -ms-flex-wrap: wrap !important;
+      flex-wrap: wrap !important;
+}
+
+.flex-nowrap {
+  -ms-flex-wrap: nowrap !important;
+      flex-wrap: nowrap !important;
+}
+
+.flex-wrap-reverse {
+  -ms-flex-wrap: wrap-reverse !important;
+      flex-wrap: wrap-reverse !important;
+}
+
+.justify-content-start {
+  -ms-flex-pack: start !important;
+      justify-content: flex-start !important;
+}
+
+.justify-content-end {
+  -ms-flex-pack: end !important;
+      justify-content: flex-end !important;
+}
+
+.justify-content-center {
+  -ms-flex-pack: center !important;
+      justify-content: center !important;
+}
+
+.justify-content-between {
+  -ms-flex-pack: justify !important;
+      justify-content: space-between !important;
+}
+
+.justify-content-around {
+  -ms-flex-pack: distribute !important;
+      justify-content: space-around !important;
+}
+
+.align-items-start {
+  -ms-flex-align: start !important;
+      align-items: flex-start !important;
+}
+
+.align-items-end {
+  -ms-flex-align: end !important;
+      align-items: flex-end !important;
+}
+
+.align-items-center {
+  -ms-flex-align: center !important;
+      align-items: center !important;
+}
+
+.align-items-baseline {
+  -ms-flex-align: baseline !important;
+      align-items: baseline !important;
+}
+
+.align-items-stretch {
+  -ms-flex-align: stretch !important;
+      align-items: stretch !important;
+}
+
+.align-content-start {
+  -ms-flex-line-pack: start !important;
+      align-content: flex-start !important;
+}
+
+.align-content-end {
+  -ms-flex-line-pack: end !important;
+      align-content: flex-end !important;
+}
+
+.align-content-center {
+  -ms-flex-line-pack: center !important;
+      align-content: center !important;
+}
+
+.align-content-between {
+  -ms-flex-line-pack: justify !important;
+      align-content: space-between !important;
+}
+
+.align-content-around {
+  -ms-flex-line-pack: distribute !important;
+      align-content: space-around !important;
+}
+
+.align-content-stretch {
+  -ms-flex-line-pack: stretch !important;
+      align-content: stretch !important;
+}
+
+.align-self-auto {
+  -ms-flex-item-align: auto !important;
+      align-self: auto !important;
+}
+
+.align-self-start {
+  -ms-flex-item-align: start !important;
+      align-self: flex-start !important;
+}
+
+.align-self-end {
+  -ms-flex-item-align: end !important;
+      align-self: flex-end !important;
+}
+
+.align-self-center {
+  -ms-flex-item-align: center !important;
+      align-self: center !important;
+}
+
+.align-self-baseline {
+  -ms-flex-item-align: baseline !important;
+      align-self: baseline !important;
+}
+
+.align-self-stretch {
+  -ms-flex-item-align: stretch !important;
+      align-self: stretch !important;
+}
+
+@media (min-width: 576px) {
+  .flex-sm-row {
+    -ms-flex-direction: row !important;
+        flex-direction: row !important;
+  }
+  .flex-sm-column {
+    -ms-flex-direction: column !important;
+        flex-direction: column !important;
+  }
+  .flex-sm-row-reverse {
+    -ms-flex-direction: row-reverse !important;
+        flex-direction: row-reverse !important;
+  }
+  .flex-sm-column-reverse {
+    -ms-flex-direction: column-reverse !important;
+        flex-direction: column-reverse !important;
+  }
+  .flex-sm-wrap {
+    -ms-flex-wrap: wrap !important;
+        flex-wrap: wrap !important;
+  }
+  .flex-sm-nowrap {
+    -ms-flex-wrap: nowrap !important;
+        flex-wrap: nowrap !important;
+  }
+  .flex-sm-wrap-reverse {
+    -ms-flex-wrap: wrap-reverse !important;
+        flex-wrap: wrap-reverse !important;
+  }
+  .justify-content-sm-start {
+    -ms-flex-pack: start !important;
+        justify-content: flex-start !important;
+  }
+  .justify-content-sm-end {
+    -ms-flex-pack: end !important;
+        justify-content: flex-end !important;
+  }
+  .justify-content-sm-center {
+    -ms-flex-pack: center !important;
+        justify-content: center !important;
+  }
+  .justify-content-sm-between {
+    -ms-flex-pack: justify !important;
+        justify-content: space-between !important;
+  }
+  .justify-content-sm-around {
+    -ms-flex-pack: distribute !important;
+        justify-content: space-around !important;
+  }
+  .align-items-sm-start {
+    -ms-flex-align: start !important;
+        align-items: flex-start !important;
+  }
+  .align-items-sm-end {
+    -ms-flex-align: end !important;
+        align-items: flex-end !important;
+  }
+  .align-items-sm-center {
+    -ms-flex-align: center !important;
+        align-items: center !important;
+  }
+  .align-items-sm-baseline {
+    -ms-flex-align: baseline !important;
+        align-items: baseline !important;
+  }
+  .align-items-sm-stretch {
+    -ms-flex-align: stretch !important;
+        align-items: stretch !important;
+  }
+  .align-content-sm-start {
+    -ms-flex-line-pack: start !important;
+        align-content: flex-start !important;
+  }
+  .align-content-sm-end {
+    -ms-flex-line-pack: end !important;
+        align-content: flex-end !important;
+  }
+  .align-content-sm-center {
+    -ms-flex-line-pack: center !important;
+        align-content: center !important;
+  }
+  .align-content-sm-between {
+    -ms-flex-line-pack: justify !important;
+        align-content: space-between !important;
+  }
+  .align-content-sm-around {
+    -ms-flex-line-pack: distribute !important;
+        align-content: space-around !important;
+  }
+  .align-content-sm-stretch {
+    -ms-flex-line-pack: stretch !important;
+        align-content: stretch !important;
+  }
+  .align-self-sm-auto {
+    -ms-flex-item-align: auto !important;
+        align-self: auto !important;
+  }
+  .align-self-sm-start {
+    -ms-flex-item-align: start !important;
+        align-self: flex-start !important;
+  }
+  .align-self-sm-end {
+    -ms-flex-item-align: end !important;
+        align-self: flex-end !important;
+  }
+  .align-self-sm-center {
+    -ms-flex-item-align: center !important;
+        align-self: center !important;
+  }
+  .align-self-sm-baseline {
+    -ms-flex-item-align: baseline !important;
+        align-self: baseline !important;
+  }
+  .align-self-sm-stretch {
+    -ms-flex-item-align: stretch !important;
+        align-self: stretch !important;
+  }
+}
+
+@media (min-width: 768px) {
+  .flex-md-row {
+    -ms-flex-direction: row !important;
+        flex-direction: row !important;
+  }
+  .flex-md-column {
+    -ms-flex-direction: column !important;
+        flex-direction: column !important;
+  }
+  .flex-md-row-reverse {
+    -ms-flex-direction: row-reverse !important;
+        flex-direction: row-reverse !important;
+  }
+  .flex-md-column-reverse {
+    -ms-flex-direction: column-reverse !important;
+        flex-direction: column-reverse !important;
+  }
+  .flex-md-wrap {
+    -ms-flex-wrap: wrap !important;
+        flex-wrap: wrap !important;
+  }
+  .flex-md-nowrap {
+    -ms-flex-wrap: nowrap !important;
+        flex-wrap: nowrap !important;
+  }
+  .flex-md-wrap-reverse {
+    -ms-flex-wrap: wrap-reverse !important;
+        flex-wrap: wrap-reverse !important;
+  }
+  .justify-content-md-start {
+    -ms-flex-pack: start !important;
+        justify-content: flex-start !important;
+  }
+  .justify-content-md-end {
+    -ms-flex-pack: end !important;
+        justify-content: flex-end !important;
+  }
+  .justify-content-md-center {
+    -ms-flex-pack: center !important;
+        justify-content: center !important;
+  }
+  .justify-content-md-between {
+    -ms-flex-pack: justify !important;
+        justify-content: space-between !important;
+  }
+  .justify-content-md-around {
+    -ms-flex-pack: distribute !important;
+        justify-content: space-around !important;
+  }
+  .align-items-md-start {
+    -ms-flex-align: start !important;
+        align-items: flex-start !important;
+  }
+  .align-items-md-end {
+    -ms-flex-align: end !important;
+        align-items: flex-end !important;
+  }
+  .align-items-md-center {
+    -ms-flex-align: center !important;
+        align-items: center !important;
+  }
+  .align-items-md-baseline {
+    -ms-flex-align: baseline !important;
+        align-items: baseline !important;
+  }
+  .align-items-md-stretch {
+    -ms-flex-align: stretch !important;
+        align-items: stretch !important;
+  }
+  .align-content-md-start {
+    -ms-flex-line-pack: start !important;
+        align-content: flex-start !important;
+  }
+  .align-content-md-end {
+    -ms-flex-line-pack: end !important;
+        align-content: flex-end !important;
+  }
+  .align-content-md-center {
+    -ms-flex-line-pack: center !important;
+        align-content: center !important;
+  }
+  .align-content-md-between {
+    -ms-flex-line-pack: justify !important;
+        align-content: space-between !important;
+  }
+  .align-content-md-around {
+    -ms-flex-line-pack: distribute !important;
+        align-content: space-around !important;
+  }
+  .align-content-md-stretch {
+    -ms-flex-line-pack: stretch !important;
+        align-content: stretch !important;
+  }
+  .align-self-md-auto {
+    -ms-flex-item-align: auto !important;
+        align-self: auto !important;
+  }
+  .align-self-md-start {
+    -ms-flex-item-align: start !important;
+        align-self: flex-start !important;
+  }
+  .align-self-md-end {
+    -ms-flex-item-align: end !important;
+        align-self: flex-end !important;
+  }
+  .align-self-md-center {
+    -ms-flex-item-align: center !important;
+        align-self: center !important;
+  }
+  .align-self-md-baseline {
+    -ms-flex-item-align: baseline !important;
+        align-self: baseline !important;
+  }
+  .align-self-md-stretch {
+    -ms-flex-item-align: stretch !important;
+        align-self: stretch !important;
+  }
+}
+
+@media (min-width: 992px) {
+  .flex-lg-row {
+    -ms-flex-direction: row !important;
+        flex-direction: row !important;
+  }
+  .flex-lg-column {
+    -ms-flex-direction: column !important;
+        flex-direction: column !important;
+  }
+  .flex-lg-row-reverse {
+    -ms-flex-direction: row-reverse !important;
+        flex-direction: row-reverse !important;
+  }
+  .flex-lg-column-reverse {
+    -ms-flex-direction: column-reverse !important;
+        flex-direction: column-reverse !important;
+  }
+  .flex-lg-wrap {
+    -ms-flex-wrap: wrap !important;
+        flex-wrap: wrap !important;
+  }
+  .flex-lg-nowrap {
+    -ms-flex-wrap: nowrap !important;
+        flex-wrap: nowrap !important;
+  }
+  .flex-lg-wrap-reverse {
+    -ms-flex-wrap: wrap-reverse !important;
+        flex-wrap: wrap-reverse !important;
+  }
+  .justify-content-lg-start {
+    -ms-flex-pack: start !important;
+        justify-content: flex-start !important;
+  }
+  .justify-content-lg-end {
+    -ms-flex-pack: end !important;
+        justify-content: flex-end !important;
+  }
+  .justify-content-lg-center {
+    -ms-flex-pack: center !important;
+        justify-content: center !important;
+  }
+  .justify-content-lg-between {
+    -ms-flex-pack: justify !important;
+        justify-content: space-between !important;
+  }
+  .justify-content-lg-around {
+    -ms-flex-pack: distribute !important;
+        justify-content: space-around !important;
+  }
+  .align-items-lg-start {
+    -ms-flex-align: start !important;
+        align-items: flex-start !important;
+  }
+  .align-items-lg-end {
+    -ms-flex-align: end !important;
+        align-items: flex-end !important;
+  }
+  .align-items-lg-center {
+    -ms-flex-align: center !important;
+        align-items: center !important;
+  }
+  .align-items-lg-baseline {
+    -ms-flex-align: baseline !important;
+        align-items: baseline !important;
+  }
+  .align-items-lg-stretch {
+    -ms-flex-align: stretch !important;
+        align-items: stretch !important;
+  }
+  .align-content-lg-start {
+    -ms-flex-line-pack: start !important;
+        align-content: flex-start !important;
+  }
+  .align-content-lg-end {
+    -ms-flex-line-pack: end !important;
+        align-content: flex-end !important;
+  }
+  .align-content-lg-center {
+    -ms-flex-line-pack: center !important;
+        align-content: center !important;
+  }
+  .align-content-lg-between {
+    -ms-flex-line-pack: justify !important;
+        align-content: space-between !important;
+  }
+  .align-content-lg-around {
+    -ms-flex-line-pack: distribute !important;
+        align-content: space-around !important;
+  }
+  .align-content-lg-stretch {
+    -ms-flex-line-pack: stretch !important;
+        align-content: stretch !important;
+  }
+  .align-self-lg-auto {
+    -ms-flex-item-align: auto !important;
+        align-self: auto !important;
+  }
+  .align-self-lg-start {
+    -ms-flex-item-align: start !important;
+        align-self: flex-start !important;
+  }
+  .align-self-lg-end {
+    -ms-flex-item-align: end !important;
+        align-self: flex-end !important;
+  }
+  .align-self-lg-center {
+    -ms-flex-item-align: center !important;
+        align-self: center !important;
+  }
+  .align-self-lg-baseline {
+    -ms-flex-item-align: baseline !important;
+        align-self: baseline !important;
+  }
+  .align-self-lg-stretch {
+    -ms-flex-item-align: stretch !important;
+        align-self: stretch !important;
+  }
+}
+
+@media (min-width: 1200px) {
+  .flex-xl-row {
+    -ms-flex-direction: row !important;
+        flex-direction: row !important;
+  }
+  .flex-xl-column {
+    -ms-flex-direction: column !important;
+        flex-direction: column !important;
+  }
+  .flex-xl-row-reverse {
+    -ms-flex-direction: row-reverse !important;
+        flex-direction: row-reverse !important;
+  }
+  .flex-xl-column-reverse {
+    -ms-flex-direction: column-reverse !important;
+        flex-direction: column-reverse !important;
+  }
+  .flex-xl-wrap {
+    -ms-flex-wrap: wrap !important;
+        flex-wrap: wrap !important;
+  }
+  .flex-xl-nowrap {
+    -ms-flex-wrap: nowrap !important;
+        flex-wrap: nowrap !important;
+  }
+  .flex-xl-wrap-reverse {
+    -ms-flex-wrap: wrap-reverse !important;
+        flex-wrap: wrap-reverse !important;
+  }
+  .justify-content-xl-start {
+    -ms-flex-pack: start !important;
+        justify-content: flex-start !important;
+  }
+  .justify-content-xl-end {
+    -ms-flex-pack: end !important;
+        justify-content: flex-end !important;
+  }
+  .justify-content-xl-center {
+    -ms-flex-pack: center !important;
+        justify-content: center !important;
+  }
+  .justify-content-xl-between {
+    -ms-flex-pack: justify !important;
+        justify-content: space-between !important;
+  }
+  .justify-content-xl-around {
+    -ms-flex-pack: distribute !important;
+        justify-content: space-around !important;
+  }
+  .align-items-xl-start {
+    -ms-flex-align: start !important;
+        align-items: flex-start !important;
+  }
+  .align-items-xl-end {
+    -ms-flex-align: end !important;
+        align-items: flex-end !important;
+  }
+  .align-items-xl-center {
+    -ms-flex-align: center !important;
+        align-items: center !important;
+  }
+  .align-items-xl-baseline {
+    -ms-flex-align: baseline !important;
+        align-items: baseline !important;
+  }
+  .align-items-xl-stretch {
+    -ms-flex-align: stretch !important;
+        align-items: stretch !important;
+  }
+  .align-content-xl-start {
+    -ms-flex-line-pack: start !important;
+        align-content: flex-start !important;
+  }
+  .align-content-xl-end {
+    -ms-flex-line-pack: end !important;
+        align-content: flex-end !important;
+  }
+  .align-content-xl-center {
+    -ms-flex-line-pack: center !important;
+        align-content: center !important;
+  }
+  .align-content-xl-between {
+    -ms-flex-line-pack: justify !important;
+        align-content: space-between !important;
+  }
+  .align-content-xl-around {
+    -ms-flex-line-pack: distribute !important;
+        align-content: space-around !important;
+  }
+  .align-content-xl-stretch {
+    -ms-flex-line-pack: stretch !important;
+        align-content: stretch !important;
+  }
+  .align-self-xl-auto {
+    -ms-flex-item-align: auto !important;
+        align-self: auto !important;
+  }
+  .align-self-xl-start {
+    -ms-flex-item-align: start !important;
+        align-self: flex-start !important;
+  }
+  .align-self-xl-end {
+    -ms-flex-item-align: end !important;
+        align-self: flex-end !important;
+  }
+  .align-self-xl-center {
+    -ms-flex-item-align: center !important;
+        align-self: center !important;
+  }
+  .align-self-xl-baseline {
+    -ms-flex-item-align: baseline !important;
+        align-self: baseline !important;
+  }
+  .align-self-xl-stretch {
+    -ms-flex-item-align: stretch !important;
+        align-self: stretch !important;
+  }
+}
+
+.float-left {
+  float: left !important;
+}
+
+.float-right {
+  float: right !important;
+}
+
+.float-none {
+  float: none !important;
+}
+
+@media (min-width: 576px) {
+  .float-sm-left {
+    float: left !important;
+  }
+  .float-sm-right {
+    float: right !important;
+  }
+  .float-sm-none {
+    float: none !important;
+  }
+}
+
+@media (min-width: 768px) {
+  .float-md-left {
+    float: left !important;
+  }
+  .float-md-right {
+    float: right !important;
+  }
+  .float-md-none {
+    float: none !important;
+  }
+}
+
+@media (min-width: 992px) {
+  .float-lg-left {
+    float: left !important;
+  }
+  .float-lg-right {
+    float: right !important;
+  }
+  .float-lg-none {
+    float: none !important;
+  }
+}
+
+@media (min-width: 1200px) {
+  .float-xl-left {
+    float: left !important;
+  }
+  .float-xl-right {
+    float: right !important;
+  }
+  .float-xl-none {
+    float: none !important;
+  }
+}
+
+.position-static {
+  position: static !important;
+}
+
+.position-relative {
+  position: relative !important;
+}
+
+.position-absolute {
+  position: absolute !important;
+}
+
+.position-fixed {
+  position: fixed !important;
+}
+
+.position-sticky {
+  position: -webkit-sticky !important;
+  position: sticky !important;
+}
+
+.fixed-top {
+  position: fixed;
+  top: 0;
+  right: 0;
+  left: 0;
+  z-index: 1030;
+}
+
+.fixed-bottom {
+  position: fixed;
+  right: 0;
+  bottom: 0;
+  left: 0;
+  z-index: 1030;
+}
+
+@supports ((position: -webkit-sticky) or (position: sticky)) {
+  .sticky-top {
+    position: -webkit-sticky;
+    position: sticky;
+    top: 0;
+    z-index: 1020;
+  }
+}
+
+.sr-only {
+  position: absolute;
+  width: 1px;
+  height: 1px;
+  padding: 0;
+  overflow: hidden;
+  clip: rect(0, 0, 0, 0);
+  white-space: nowrap;
+  -webkit-clip-path: inset(50%);
+          clip-path: inset(50%);
+  border: 0;
+}
+
+.sr-only-focusable:active, .sr-only-focusable:focus {
+  position: static;
+  width: auto;
+  height: auto;
+  overflow: visible;
+  clip: auto;
+  white-space: normal;
+  -webkit-clip-path: none;
+          clip-path: none;
+}
+
+.w-25 {
+  width: 25% !important;
+}
+
+.w-50 {
+  width: 50% !important;
+}
+
+.w-75 {
+  width: 75% !important;
+}
+
+.w-100 {
+  width: 100% !important;
+}
+
+.h-25 {
+  height: 25% !important;
+}
+
+.h-50 {
+  height: 50% !important;
+}
+
+.h-75 {
+  height: 75% !important;
+}
+
+.h-100 {
+  height: 100% !important;
+}
+
+.mw-100 {
+  max-width: 100% !important;
+}
+
+.mh-100 {
+  max-height: 100% !important;
+}
+
+.m-0 {
+  margin: 0 !important;
+}
+
+.mt-0,
+.my-0 {
+  margin-top: 0 !important;
+}
+
+.mr-0,
+.mx-0 {
+  margin-right: 0 !important;
+}
+
+.mb-0,
+.my-0 {
+  margin-bottom: 0 !important;
+}
+
+.ml-0,
+.mx-0 {
+  margin-left: 0 !important;
+}
+
+.m-1 {
+  margin: 0.25rem !important;
+}
+
+.mt-1,
+.my-1 {
+  margin-top: 0.25rem !important;
+}
+
+.mr-1,
+.mx-1 {
+  margin-right: 0.25rem !important;
+}
+
+.mb-1,
+.my-1 {
+  margin-bottom: 0.25rem !important;
+}
+
+.ml-1,
+.mx-1 {
+  margin-left: 0.25rem !important;
+}
+
+.m-2 {
+  margin: 0.5rem !important;
+}
+
+.mt-2,
+.my-2 {
+  margin-top: 0.5rem !important;
+}
+
+.mr-2,
+.mx-2 {
+  margin-right: 0.5rem !important;
+}
+
+.mb-2,
+.my-2 {
+  margin-bottom: 0.5rem !important;
+}
+
+.ml-2,
+.mx-2 {
+  margin-left: 0.5rem !important;
+}
+
+.m-3 {
+  margin: 1rem !important;
+}
+
+.mt-3,
+.my-3 {
+  margin-top: 1rem !important;
+}
+
+.mr-3,
+.mx-3 {
+  margin-right: 1rem !important;
+}
+
+.mb-3,
+.my-3 {
+  margin-bottom: 1rem !important;
+}
+
+.ml-3,
+.mx-3 {
+  margin-left: 1rem !important;
+}
+
+.m-4 {
+  margin: 1.5rem !important;
+}
+
+.mt-4,
+.my-4 {
+  margin-top: 1.5rem !important;
+}
+
+.mr-4,
+.mx-4 {
+  margin-right: 1.5rem !important;
+}
+
+.mb-4,
+.my-4 {
+  margin-bottom: 1.5rem !important;
+}
+
+.ml-4,
+.mx-4 {
+  margin-left: 1.5rem !important;
+}
+
+.m-5 {
+  margin: 3rem !important;
+}
+
+.mt-5,
+.my-5 {
+  margin-top: 3rem !important;
+}
+
+.mr-5,
+.mx-5 {
+  margin-right: 3rem !important;
+}
+
+.mb-5,
+.my-5 {
+  margin-bottom: 3rem !important;
+}
+
+.ml-5,
+.mx-5 {
+  margin-left: 3rem !important;
+}
+
+.p-0 {
+  padding: 0 !important;
+}
+
+.pt-0,
+.py-0 {
+  padding-top: 0 !important;
+}
+
+.pr-0,
+.px-0 {
+  padding-right: 0 !important;
+}
+
+.pb-0,
+.py-0 {
+  padding-bottom: 0 !important;
+}
+
+.pl-0,
+.px-0 {
+  padding-left: 0 !important;
+}
+
+.p-1 {
+  padding: 0.25rem !important;
+}
+
+.pt-1,
+.py-1 {
+  padding-top: 0.25rem !important;
+}
+
+.pr-1,
+.px-1 {
+  padding-right: 0.25rem !important;
+}
+
+.pb-1,
+.py-1 {
+  padding-bottom: 0.25rem !important;
+}
+
+.pl-1,
+.px-1 {
+  padding-left: 0.25rem !important;
+}
+
+.p-2 {
+  padding: 0.5rem !important;
+}
+
+.pt-2,
+.py-2 {
+  padding-top: 0.5rem !important;
+}
+
+.pr-2,
+.px-2 {
+  padding-right: 0.5rem !important;
+}
+
+.pb-2,
+.py-2 {
+  padding-bottom: 0.5rem !important;
+}
+
+.pl-2,
+.px-2 {
+  padding-left: 0.5rem !important;
+}
+
+.p-3 {
+  padding: 1rem !important;
+}
+
+.pt-3,
+.py-3 {
+  padding-top: 1rem !important;
+}
+
+.pr-3,
+.px-3 {
+  padding-right: 1rem !important;
+}
+
+.pb-3,
+.py-3 {
+  padding-bottom: 1rem !important;
+}
+
+.pl-3,
+.px-3 {
+  padding-left: 1rem !important;
+}
+
+.p-4 {
+  padding: 1.5rem !important;
+}
+
+.pt-4,
+.py-4 {
+  padding-top: 1.5rem !important;
+}
+
+.pr-4,
+.px-4 {
+  padding-right: 1.5rem !important;
+}
+
+.pb-4,
+.py-4 {
+  padding-bottom: 1.5rem !important;
+}
+
+.pl-4,
+.px-4 {
+  padding-left: 1.5rem !important;
+}
+
+.p-5 {
+  padding: 3rem !important;
+}
+
+.pt-5,
+.py-5 {
+  padding-top: 3rem !important;
+}
+
+.pr-5,
+.px-5 {
+  padding-right: 3rem !important;
+}
+
+.pb-5,
+.py-5 {
+  padding-bottom: 3rem !important;
+}
+
+.pl-5,
+.px-5 {
+  padding-left: 3rem !important;
+}
+
+.m-auto {
+  margin: auto !important;
+}
+
+.mt-auto,
+.my-auto {
+  margin-top: auto !important;
+}
+
+.mr-auto,
+.mx-auto {
+  margin-right: auto !important;
+}
+
+.mb-auto,
+.my-auto {
+  margin-bottom: auto !important;
+}
+
+.ml-auto,
+.mx-auto {
+  margin-left: auto !important;
+}
+
+@media (min-width: 576px) {
+  .m-sm-0 {
+    margin: 0 !important;
+  }
+  .mt-sm-0,
+  .my-sm-0 {
+    margin-top: 0 !important;
+  }
+  .mr-sm-0,
+  .mx-sm-0 {
+    margin-right: 0 !important;
+  }
+  .mb-sm-0,
+  .my-sm-0 {
+    margin-bottom: 0 !important;
+  }
+  .ml-sm-0,
+  .mx-sm-0 {
+    margin-left: 0 !important;
+  }
+  .m-sm-1 {
+    margin: 0.25rem !important;
+  }
+  .mt-sm-1,
+  .my-sm-1 {
+    margin-top: 0.25rem !important;
+  }
+  .mr-sm-1,
+  .mx-sm-1 {
+    margin-right: 0.25rem !important;
+  }
+  .mb-sm-1,
+  .my-sm-1 {
+    margin-bottom: 0.25rem !important;
+  }
+  .ml-sm-1,
+  .mx-sm-1 {
+    margin-left: 0.25rem !important;
+  }
+  .m-sm-2 {
+    margin: 0.5rem !important;
+  }
+  .mt-sm-2,
+  .my-sm-2 {
+    margin-top: 0.5rem !important;
+  }
+  .mr-sm-2,
+  .mx-sm-2 {
+    margin-right: 0.5rem !important;
+  }
+  .mb-sm-2,
+  .my-sm-2 {
+    margin-bottom: 0.5rem !important;
+  }
+  .ml-sm-2,
+  .mx-sm-2 {
+    margin-left: 0.5rem !important;
+  }
+  .m-sm-3 {
+    margin: 1rem !important;
+  }
+  .mt-sm-3,
+  .my-sm-3 {
+    margin-top: 1rem !important;
+  }
+  .mr-sm-3,
+  .mx-sm-3 {
+    margin-right: 1rem !important;
+  }
+  .mb-sm-3,
+  .my-sm-3 {
+    margin-bottom: 1rem !important;
+  }
+  .ml-sm-3,
+  .mx-sm-3 {
+    margin-left: 1rem !important;
+  }
+  .m-sm-4 {
+    margin: 1.5rem !important;
+  }
+  .mt-sm-4,
+  .my-sm-4 {
+    margin-top: 1.5rem !important;
+  }
+  .mr-sm-4,
+  .mx-sm-4 {
+    margin-right: 1.5rem !important;
+  }
+  .mb-sm-4,
+  .my-sm-4 {
+    margin-bottom: 1.5rem !important;
+  }
+  .ml-sm-4,
+  .mx-sm-4 {
+    margin-left: 1.5rem !important;
+  }
+  .m-sm-5 {
+    margin: 3rem !important;
+  }
+  .mt-sm-5,
+  .my-sm-5 {
+    margin-top: 3rem !important;
+  }
+  .mr-sm-5,
+  .mx-sm-5 {
+    margin-right: 3rem !important;
+  }
+  .mb-sm-5,
+  .my-sm-5 {
+    margin-bottom: 3rem !important;
+  }
+  .ml-sm-5,
+  .mx-sm-5 {
+    margin-left: 3rem !important;
+  }
+  .p-sm-0 {
+    padding: 0 !important;
+  }
+  .pt-sm-0,
+  .py-sm-0 {
+    padding-top: 0 !important;
+  }
+  .pr-sm-0,
+  .px-sm-0 {
+    padding-right: 0 !important;
+  }
+  .pb-sm-0,
+  .py-sm-0 {
+    padding-bottom: 0 !important;
+  }
+  .pl-sm-0,
+  .px-sm-0 {
+    padding-left: 0 !important;
+  }
+  .p-sm-1 {
+    padding: 0.25rem !important;
+  }
+  .pt-sm-1,
+  .py-sm-1 {
+    padding-top: 0.25rem !important;
+  }
+  .pr-sm-1,
+  .px-sm-1 {
+    padding-right: 0.25rem !important;
+  }
+  .pb-sm-1,
+  .py-sm-1 {
+    padding-bottom: 0.25rem !important;
+  }
+  .pl-sm-1,
+  .px-sm-1 {
+    padding-left: 0.25rem !important;
+  }
+  .p-sm-2 {
+    padding: 0.5rem !important;
+  }
+  .pt-sm-2,
+  .py-sm-2 {
+    padding-top: 0.5rem !important;
+  }
+  .pr-sm-2,
+  .px-sm-2 {
+    padding-right: 0.5rem !important;
+  }
+  .pb-sm-2,
+  .py-sm-2 {
+    padding-bottom: 0.5rem !important;
+  }
+  .pl-sm-2,
+  .px-sm-2 {
+    padding-left: 0.5rem !important;
+  }
+  .p-sm-3 {
+    padding: 1rem !important;
+  }
+  .pt-sm-3,
+  .py-sm-3 {
+    padding-top: 1rem !important;
+  }
+  .pr-sm-3,
+  .px-sm-3 {
+    padding-right: 1rem !important;
+  }
+  .pb-sm-3,
+  .py-sm-3 {
+    padding-bottom: 1rem !important;
+  }
+  .pl-sm-3,
+  .px-sm-3 {
+    padding-left: 1rem !important;
+  }
+  .p-sm-4 {
+    padding: 1.5rem !important;
+  }
+  .pt-sm-4,
+  .py-sm-4 {
+    padding-top: 1.5rem !important;
+  }
+  .pr-sm-4,
+  .px-sm-4 {
+    padding-right: 1.5rem !important;
+  }
+  .pb-sm-4,
+  .py-sm-4 {
+    padding-bottom: 1.5rem !important;
+  }
+  .pl-sm-4,
+  .px-sm-4 {
+    padding-left: 1.5rem !important;
+  }
+  .p-sm-5 {
+    padding: 3rem !important;
+  }
+  .pt-sm-5,
+  .py-sm-5 {
+    padding-top: 3rem !important;
+  }
+  .pr-sm-5,
+  .px-sm-5 {
+    padding-right: 3rem !important;
+  }
+  .pb-sm-5,
+  .py-sm-5 {
+    padding-bottom: 3rem !important;
+  }
+  .pl-sm-5,
+  .px-sm-5 {
+    padding-left: 3rem !important;
+  }
+  .m-sm-auto {
+    margin: auto !important;
+  }
+  .mt-sm-auto,
+  .my-sm-auto {
+    margin-top: auto !important;
+  }
+  .mr-sm-auto,
+  .mx-sm-auto {
+    margin-right: auto !important;
+  }
+  .mb-sm-auto,
+  .my-sm-auto {
+    margin-bottom: auto !important;
+  }
+  .ml-sm-auto,
+  .mx-sm-auto {
+    margin-left: auto !important;
+  }
+}
+
+@media (min-width: 768px) {
+  .m-md-0 {
+    margin: 0 !important;
+  }
+  .mt-md-0,
+  .my-md-0 {
+    margin-top: 0 !important;
+  }
+  .mr-md-0,
+  .mx-md-0 {
+    margin-right: 0 !important;
+  }
+  .mb-md-0,
+  .my-md-0 {
+    margin-bottom: 0 !important;
+  }
+  .ml-md-0,
+  .mx-md-0 {
+    margin-left: 0 !important;
+  }
+  .m-md-1 {
+    margin: 0.25rem !important;
+  }
+  .mt-md-1,
+  .my-md-1 {
+    margin-top: 0.25rem !important;
+  }
+  .mr-md-1,
+  .mx-md-1 {
+    margin-right: 0.25rem !important;
+  }
+  .mb-md-1,
+  .my-md-1 {
+    margin-bottom: 0.25rem !important;
+  }
+  .ml-md-1,
+  .mx-md-1 {
+    margin-left: 0.25rem !important;
+  }
+  .m-md-2 {
+    margin: 0.5rem !important;
+  }
+  .mt-md-2,
+  .my-md-2 {
+    margin-top: 0.5rem !important;
+  }
+  .mr-md-2,
+  .mx-md-2 {
+    margin-right: 0.5rem !important;
+  }
+  .mb-md-2,
+  .my-md-2 {
+    margin-bottom: 0.5rem !important;
+  }
+  .ml-md-2,
+  .mx-md-2 {
+    margin-left: 0.5rem !important;
+  }
+  .m-md-3 {
+    margin: 1rem !important;
+  }
+  .mt-md-3,
+  .my-md-3 {
+    margin-top: 1rem !important;
+  }
+  .mr-md-3,
+  .mx-md-3 {
+    margin-right: 1rem !important;
+  }
+  .mb-md-3,
+  .my-md-3 {
+    margin-bottom: 1rem !important;
+  }
+  .ml-md-3,
+  .mx-md-3 {
+    margin-left: 1rem !important;
+  }
+  .m-md-4 {
+    margin: 1.5rem !important;
+  }
+  .mt-md-4,
+  .my-md-4 {
+    margin-top: 1.5rem !important;
+  }
+  .mr-md-4,
+  .mx-md-4 {
+    margin-right: 1.5rem !important;
+  }
+  .mb-md-4,
+  .my-md-4 {
+    margin-bottom: 1.5rem !important;
+  }
+  .ml-md-4,
+  .mx-md-4 {
+    margin-left: 1.5rem !important;
+  }
+  .m-md-5 {
+    margin: 3rem !important;
+  }
+  .mt-md-5,
+  .my-md-5 {
+    margin-top: 3rem !important;
+  }
+  .mr-md-5,
+  .mx-md-5 {
+    margin-right: 3rem !important;
+  }
+  .mb-md-5,
+  .my-md-5 {
+    margin-bottom: 3rem !important;
+  }
+  .ml-md-5,
+  .mx-md-5 {
+    margin-left: 3rem !important;
+  }
+  .p-md-0 {
+    padding: 0 !important;
+  }
+  .pt-md-0,
+  .py-md-0 {
+    padding-top: 0 !important;
+  }
+  .pr-md-0,
+  .px-md-0 {
+    padding-right: 0 !important;
+  }
+  .pb-md-0,
+  .py-md-0 {
+    padding-bottom: 0 !important;
+  }
+  .pl-md-0,
+  .px-md-0 {
+    padding-left: 0 !important;
+  }
+  .p-md-1 {
+    padding: 0.25rem !important;
+  }
+  .pt-md-1,
+  .py-md-1 {
+    padding-top: 0.25rem !important;
+  }
+  .pr-md-1,
+  .px-md-1 {
+    padding-right: 0.25rem !important;
+  }
+  .pb-md-1,
+  .py-md-1 {
+    padding-bottom: 0.25rem !important;
+  }
+  .pl-md-1,
+  .px-md-1 {
+    padding-left: 0.25rem !important;
+  }
+  .p-md-2 {
+    padding: 0.5rem !important;
+  }
+  .pt-md-2,
+  .py-md-2 {
+    padding-top: 0.5rem !important;
+  }
+  .pr-md-2,
+  .px-md-2 {
+    padding-right: 0.5rem !important;
+  }
+  .pb-md-2,
+  .py-md-2 {
+    padding-bottom: 0.5rem !important;
+  }
+  .pl-md-2,
+  .px-md-2 {
+    padding-left: 0.5rem !important;
+  }
+  .p-md-3 {
+    padding: 1rem !important;
+  }
+  .pt-md-3,
+  .py-md-3 {
+    padding-top: 1rem !important;
+  }
+  .pr-md-3,
+  .px-md-3 {
+    padding-right: 1rem !important;
+  }
+  .pb-md-3,
+  .py-md-3 {
+    padding-bottom: 1rem !important;
+  }
+  .pl-md-3,
+  .px-md-3 {
+    padding-left: 1rem !important;
+  }
+  .p-md-4 {
+    padding: 1.5rem !important;
+  }
+  .pt-md-4,
+  .py-md-4 {
+    padding-top: 1.5rem !important;
+  }
+  .pr-md-4,
+  .px-md-4 {
+    padding-right: 1.5rem !important;
+  }
+  .pb-md-4,
+  .py-md-4 {
+    padding-bottom: 1.5rem !important;
+  }
+  .pl-md-4,
+  .px-md-4 {
+    padding-left: 1.5rem !important;
+  }
+  .p-md-5 {
+    padding: 3rem !important;
+  }
+  .pt-md-5,
+  .py-md-5 {
+    padding-top: 3rem !important;
+  }
+  .pr-md-5,
+  .px-md-5 {
+    padding-right: 3rem !important;
+  }
+  .pb-md-5,
+  .py-md-5 {
+    padding-bottom: 3rem !important;
+  }
+  .pl-md-5,
+  .px-md-5 {
+    padding-left: 3rem !important;
+  }
+  .m-md-auto {
+    margin: auto !important;
+  }
+  .mt-md-auto,
+  .my-md-auto {
+    margin-top: auto !important;
+  }
+  .mr-md-auto,
+  .mx-md-auto {
+    margin-right: auto !important;
+  }
+  .mb-md-auto,
+  .my-md-auto {
+    margin-bottom: auto !important;
+  }
+  .ml-md-auto,
+  .mx-md-auto {
+    margin-left: auto !important;
+  }
+}
+
+@media (min-width: 992px) {
+  .m-lg-0 {
+    margin: 0 !important;
+  }
+  .mt-lg-0,
+  .my-lg-0 {
+    margin-top: 0 !important;
+  }
+  .mr-lg-0,
+  .mx-lg-0 {
+    margin-right: 0 !important;
+  }
+  .mb-lg-0,
+  .my-lg-0 {
+    margin-bottom: 0 !important;
+  }
+  .ml-lg-0,
+  .mx-lg-0 {
+    margin-left: 0 !important;
+  }
+  .m-lg-1 {
+    margin: 0.25rem !important;
+  }
+  .mt-lg-1,
+  .my-lg-1 {
+    margin-top: 0.25rem !important;
+  }
+  .mr-lg-1,
+  .mx-lg-1 {
+    margin-right: 0.25rem !important;
+  }
+  .mb-lg-1,
+  .my-lg-1 {
+    margin-bottom: 0.25rem !important;
+  }
+  .ml-lg-1,
+  .mx-lg-1 {
+    margin-left: 0.25rem !important;
+  }
+  .m-lg-2 {
+    margin: 0.5rem !important;
+  }
+  .mt-lg-2,
+  .my-lg-2 {
+    margin-top: 0.5rem !important;
+  }
+  .mr-lg-2,
+  .mx-lg-2 {
+    margin-right: 0.5rem !important;
+  }
+  .mb-lg-2,
+  .my-lg-2 {
+    margin-bottom: 0.5rem !important;
+  }
+  .ml-lg-2,
+  .mx-lg-2 {
+    margin-left: 0.5rem !important;
+  }
+  .m-lg-3 {
+    margin: 1rem !important;
+  }
+  .mt-lg-3,
+  .my-lg-3 {
+    margin-top: 1rem !important;
+  }
+  .mr-lg-3,
+  .mx-lg-3 {
+    margin-right: 1rem !important;
+  }
+  .mb-lg-3,
+  .my-lg-3 {
+    margin-bottom: 1rem !important;
+  }
+  .ml-lg-3,
+  .mx-lg-3 {
+    margin-left: 1rem !important;
+  }
+  .m-lg-4 {
+    margin: 1.5rem !important;
+  }
+  .mt-lg-4,
+  .my-lg-4 {
+    margin-top: 1.5rem !important;
+  }
+  .mr-lg-4,
+  .mx-lg-4 {
+    margin-right: 1.5rem !important;
+  }
+  .mb-lg-4,
+  .my-lg-4 {
+    margin-bottom: 1.5rem !important;
+  }
+  .ml-lg-4,
+  .mx-lg-4 {
+    margin-left: 1.5rem !important;
+  }
+  .m-lg-5 {
+    margin: 3rem !important;
+  }
+  .mt-lg-5,
+  .my-lg-5 {
+    margin-top: 3rem !important;
+  }
+  .mr-lg-5,
+  .mx-lg-5 {
+    margin-right: 3rem !important;
+  }
+  .mb-lg-5,
+  .my-lg-5 {
+    margin-bottom: 3rem !important;
+  }
+  .ml-lg-5,
+  .mx-lg-5 {
+    margin-left: 3rem !important;
+  }
+  .p-lg-0 {
+    padding: 0 !important;
+  }
+  .pt-lg-0,
+  .py-lg-0 {
+    padding-top: 0 !important;
+  }
+  .pr-lg-0,
+  .px-lg-0 {
+    padding-right: 0 !important;
+  }
+  .pb-lg-0,
+  .py-lg-0 {
+    padding-bottom: 0 !important;
+  }
+  .pl-lg-0,
+  .px-lg-0 {
+    padding-left: 0 !important;
+  }
+  .p-lg-1 {
+    padding: 0.25rem !important;
+  }
+  .pt-lg-1,
+  .py-lg-1 {
+    padding-top: 0.25rem !important;
+  }
+  .pr-lg-1,
+  .px-lg-1 {
+    padding-right: 0.25rem !important;
+  }
+  .pb-lg-1,
+  .py-lg-1 {
+    padding-bottom: 0.25rem !important;
+  }
+  .pl-lg-1,
+  .px-lg-1 {
+    padding-left: 0.25rem !important;
+  }
+  .p-lg-2 {
+    padding: 0.5rem !important;
+  }
+  .pt-lg-2,
+  .py-lg-2 {
+    padding-top: 0.5rem !important;
+  }
+  .pr-lg-2,
+  .px-lg-2 {
+    padding-right: 0.5rem !important;
+  }
+  .pb-lg-2,
+  .py-lg-2 {
+    padding-bottom: 0.5rem !important;
+  }
+  .pl-lg-2,
+  .px-lg-2 {
+    padding-left: 0.5rem !important;
+  }
+  .p-lg-3 {
+    padding: 1rem !important;
+  }
+  .pt-lg-3,
+  .py-lg-3 {
+    padding-top: 1rem !important;
+  }
+  .pr-lg-3,
+  .px-lg-3 {
+    padding-right: 1rem !important;
+  }
+  .pb-lg-3,
+  .py-lg-3 {
+    padding-bottom: 1rem !important;
+  }
+  .pl-lg-3,
+  .px-lg-3 {
+    padding-left: 1rem !important;
+  }
+  .p-lg-4 {
+    padding: 1.5rem !important;
+  }
+  .pt-lg-4,
+  .py-lg-4 {
+    padding-top: 1.5rem !important;
+  }
+  .pr-lg-4,
+  .px-lg-4 {
+    padding-right: 1.5rem !important;
+  }
+  .pb-lg-4,
+  .py-lg-4 {
+    padding-bottom: 1.5rem !important;
+  }
+  .pl-lg-4,
+  .px-lg-4 {
+    padding-left: 1.5rem !important;
+  }
+  .p-lg-5 {
+    padding: 3rem !important;
+  }
+  .pt-lg-5,
+  .py-lg-5 {
+    padding-top: 3rem !important;
+  }
+  .pr-lg-5,
+  .px-lg-5 {
+    padding-right: 3rem !important;
+  }
+  .pb-lg-5,
+  .py-lg-5 {
+    padding-bottom: 3rem !important;
+  }
+  .pl-lg-5,
+  .px-lg-5 {
+    padding-left: 3rem !important;
+  }
+  .m-lg-auto {
+    margin: auto !important;
+  }
+  .mt-lg-auto,
+  .my-lg-auto {
+    margin-top: auto !important;
+  }
+  .mr-lg-auto,
+  .mx-lg-auto {
+    margin-right: auto !important;
+  }
+  .mb-lg-auto,
+  .my-lg-auto {
+    margin-bottom: auto !important;
+  }
+  .ml-lg-auto,
+  .mx-lg-auto {
+    margin-left: auto !important;
+  }
+}
+
+@media (min-width: 1200px) {
+  .m-xl-0 {
+    margin: 0 !important;
+  }
+  .mt-xl-0,
+  .my-xl-0 {
+    margin-top: 0 !important;
+  }
+  .mr-xl-0,
+  .mx-xl-0 {
+    margin-right: 0 !important;
+  }
+  .mb-xl-0,
+  .my-xl-0 {
+    margin-bottom: 0 !important;
+  }
+  .ml-xl-0,
+  .mx-xl-0 {
+    margin-left: 0 !important;
+  }
+  .m-xl-1 {
+    margin: 0.25rem !important;
+  }
+  .mt-xl-1,
+  .my-xl-1 {
+    margin-top: 0.25rem !important;
+  }
+  .mr-xl-1,
+  .mx-xl-1 {
+    margin-right: 0.25rem !important;
+  }
+  .mb-xl-1,
+  .my-xl-1 {
+    margin-bottom: 0.25rem !important;
+  }
+  .ml-xl-1,
+  .mx-xl-1 {
+    margin-left: 0.25rem !important;
+  }
+  .m-xl-2 {
+    margin: 0.5rem !important;
+  }
+  .mt-xl-2,
+  .my-xl-2 {
+    margin-top: 0.5rem !important;
+  }
+  .mr-xl-2,
+  .mx-xl-2 {
+    margin-right: 0.5rem !important;
+  }
+  .mb-xl-2,
+  .my-xl-2 {
+    margin-bottom: 0.5rem !important;
+  }
+  .ml-xl-2,
+  .mx-xl-2 {
+    margin-left: 0.5rem !important;
+  }
+  .m-xl-3 {
+    margin: 1rem !important;
+  }
+  .mt-xl-3,
+  .my-xl-3 {
+    margin-top: 1rem !important;
+  }
+  .mr-xl-3,
+  .mx-xl-3 {
+    margin-right: 1rem !important;
+  }
+  .mb-xl-3,
+  .my-xl-3 {
+    margin-bottom: 1rem !important;
+  }
+  .ml-xl-3,
+  .mx-xl-3 {
+    margin-left: 1rem !important;
+  }
+  .m-xl-4 {
+    margin: 1.5rem !important;
+  }
+  .mt-xl-4,
+  .my-xl-4 {
+    margin-top: 1.5rem !important;
+  }
+  .mr-xl-4,
+  .mx-xl-4 {
+    margin-right: 1.5rem !important;
+  }
+  .mb-xl-4,
+  .my-xl-4 {
+    margin-bottom: 1.5rem !important;
+  }
+  .ml-xl-4,
+  .mx-xl-4 {
+    margin-left: 1.5rem !important;
+  }
+  .m-xl-5 {
+    margin: 3rem !important;
+  }
+  .mt-xl-5,
+  .my-xl-5 {
+    margin-top: 3rem !important;
+  }
+  .mr-xl-5,
+  .mx-xl-5 {
+    margin-right: 3rem !important;
+  }
+  .mb-xl-5,
+  .my-xl-5 {
+    margin-bottom: 3rem !important;
+  }
+  .ml-xl-5,
+  .mx-xl-5 {
+    margin-left: 3rem !important;
+  }
+  .p-xl-0 {
+    padding: 0 !important;
+  }
+  .pt-xl-0,
+  .py-xl-0 {
+    padding-top: 0 !important;
+  }
+  .pr-xl-0,
+  .px-xl-0 {
+    padding-right: 0 !important;
+  }
+  .pb-xl-0,
+  .py-xl-0 {
+    padding-bottom: 0 !important;
+  }
+  .pl-xl-0,
+  .px-xl-0 {
+    padding-left: 0 !important;
+  }
+  .p-xl-1 {
+    padding: 0.25rem !important;
+  }
+  .pt-xl-1,
+  .py-xl-1 {
+    padding-top: 0.25rem !important;
+  }
+  .pr-xl-1,
+  .px-xl-1 {
+    padding-right: 0.25rem !important;
+  }
+  .pb-xl-1,
+  .py-xl-1 {
+    padding-bottom: 0.25rem !important;
+  }
+  .pl-xl-1,
+  .px-xl-1 {
+    padding-left: 0.25rem !important;
+  }
+  .p-xl-2 {
+    padding: 0.5rem !important;
+  }
+  .pt-xl-2,
+  .py-xl-2 {
+    padding-top: 0.5rem !important;
+  }
+  .pr-xl-2,
+  .px-xl-2 {
+    padding-right: 0.5rem !important;
+  }
+  .pb-xl-2,
+  .py-xl-2 {
+    padding-bottom: 0.5rem !important;
+  }
+  .pl-xl-2,
+  .px-xl-2 {
+    padding-left: 0.5rem !important;
+  }
+  .p-xl-3 {
+    padding: 1rem !important;
+  }
+  .pt-xl-3,
+  .py-xl-3 {
+    padding-top: 1rem !important;
+  }
+  .pr-xl-3,
+  .px-xl-3 {
+    padding-right: 1rem !important;
+  }
+  .pb-xl-3,
+  .py-xl-3 {
+    padding-bottom: 1rem !important;
+  }
+  .pl-xl-3,
+  .px-xl-3 {
+    padding-left: 1rem !important;
+  }
+  .p-xl-4 {
+    padding: 1.5rem !important;
+  }
+  .pt-xl-4,
+  .py-xl-4 {
+    padding-top: 1.5rem !important;
+  }
+  .pr-xl-4,
+  .px-xl-4 {
+    padding-right: 1.5rem !important;
+  }
+  .pb-xl-4,
+  .py-xl-4 {
+    padding-bottom: 1.5rem !important;
+  }
+  .pl-xl-4,
+  .px-xl-4 {
+    padding-left: 1.5rem !important;
+  }
+  .p-xl-5 {
+    padding: 3rem !important;
+  }
+  .pt-xl-5,
+  .py-xl-5 {
+    padding-top: 3rem !important;
+  }
+  .pr-xl-5,
+  .px-xl-5 {
+    padding-right: 3rem !important;
+  }
+  .pb-xl-5,
+  .py-xl-5 {
+    padding-bottom: 3rem !important;
+  }
+  .pl-xl-5,
+  .px-xl-5 {
+    padding-left: 3rem !important;
+  }
+  .m-xl-auto {
+    margin: auto !important;
+  }
+  .mt-xl-auto,
+  .my-xl-auto {
+    margin-top: auto !important;
+  }
+  .mr-xl-auto,
+  .mx-xl-auto {
+    margin-right: auto !important;
+  }
+  .mb-xl-auto,
+  .my-xl-auto {
+    margin-bottom: auto !important;
+  }
+  .ml-xl-auto,
+  .mx-xl-auto {
+    margin-left: auto !important;
+  }
+}
+
+.text-justify {
+  text-align: justify !important;
+}
+
+.text-nowrap {
+  white-space: nowrap !important;
+}
+
+.text-truncate {
+  overflow: hidden;
+  text-overflow: ellipsis;
+  white-space: nowrap;
+}
+
+.text-left {
+  text-align: left !important;
+}
+
+.text-right {
+  text-align: right !important;
+}
+
+.text-center {
+  text-align: center !important;
+}
+
+@media (min-width: 576px) {
+  .text-sm-left {
+    text-align: left !important;
+  }
+  .text-sm-right {
+    text-align: right !important;
+  }
+  .text-sm-center {
+    text-align: center !important;
+  }
+}
+
+@media (min-width: 768px) {
+  .text-md-left {
+    text-align: left !important;
+  }
+  .text-md-right {
+    text-align: right !important;
+  }
+  .text-md-center {
+    text-align: center !important;
+  }
+}
+
+@media (min-width: 992px) {
+  .text-lg-left {
+    text-align: left !important;
+  }
+  .text-lg-right {
+    text-align: right !important;
+  }
+  .text-lg-center {
+    text-align: center !important;
+  }
+}
+
+@media (min-width: 1200px) {
+  .text-xl-left {
+    text-align: left !important;
+  }
+  .text-xl-right {
+    text-align: right !important;
+  }
+  .text-xl-center {
+    text-align: center !important;
+  }
+}
+
+.text-lowercase {
+  text-transform: lowercase !important;
+}
+
+.text-uppercase {
+  text-transform: uppercase !important;
+}
+
+.text-capitalize {
+  text-transform: capitalize !important;
+}
+
+.font-weight-light {
+  font-weight: 300 !important;
+}
+
+.font-weight-normal {
+  font-weight: 400 !important;
+}
+
+.font-weight-bold {
+  font-weight: 700 !important;
+}
+
+.font-italic {
+  font-style: italic !important;
+}
+
+.text-white {
+  color: #fff !important;
+}
+
+.text-primary {
+  color: #007bff !important;
+}
+
+a.text-primary:focus, a.text-primary:hover {
+  color: #0062cc !important;
+}
+
+.text-secondary {
+  color: #868e96 !important;
+}
+
+a.text-secondary:focus, a.text-secondary:hover {
+  color: #6c757d !important;
+}
+
+.text-success {
+  color: #28a745 !important;
+}
+
+a.text-success:focus, a.text-success:hover {
+  color: #1e7e34 !important;
+}
+
+.text-info {
+  color: #17a2b8 !important;
+}
+
+a.text-info:focus, a.text-info:hover {
+  color: #117a8b !important;
+}
+
+.text-warning {
+  color: #ffc107 !important;
+}
+
+a.text-warning:focus, a.text-warning:hover {
+  color: #d39e00 !important;
+}
+
+.text-danger {
+  color: #dc3545 !important;
+}
+
+a.text-danger:focus, a.text-danger:hover {
+  color: #bd2130 !important;
+}
+
+.text-light {
+  color: #f8f9fa !important;
+}
+
+a.text-light:focus, a.text-light:hover {
+  color: #dae0e5 !important;
+}
+
+.text-dark {
+  color: #343a40 !important;
+}
+
+a.text-dark:focus, a.text-dark:hover {
+  color: #1d2124 !important;
+}
+
+.text-muted {
+  color: #868e96 !important;
+}
+
+.text-hide {
+  font: 0/0 a;
+  color: transparent;
+  text-shadow: none;
+  background-color: transparent;
+  border: 0;
+}
+
+.visible {
+  visibility: visible !important;
+}
+
+.invisible {
+  visibility: hidden !important;
+}
+/*# sourceMappingURL=bootstrap.css.map */
diff --git a/src/sass/compass-sass-base/_open_iconic_bootstrap.scss 
b/src/sass/compass-sass-base/_open_iconic_bootstrap.scss
new file mode 100644
index 0000000..993cf84
--- /dev/null
+++ b/src/sass/compass-sass-base/_open_iconic_bootstrap.scss
@@ -0,0 +1,957 @@
+/* Bootstrap */
+
+/* Override Bootstrap default variable */
+$icon-font-path: '../fonts/' !default;
+
+@font-face {
+  font-family: 'Icons';
+  src: url('#{$icon-font-path}open-iconic.eot');
+  src: url('#{$icon-font-path}open-iconic.eot?#iconic-sm') format('embedded-opentype'), 
url('#{$icon-font-path}open-iconic.woff') format('woff'), url('#{$icon-font-path}open-iconic.ttf') 
format('truetype'), url('#{$icon-font-path}open-iconic.svg#iconic-sm') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+
+// Catchall baseclass
+.oi {
+  position: relative;
+  top: 1px;
+  display: inline-block;
+  font-family: 'Icons';
+  font-style: normal;
+  font-weight: normal;
+  line-height: 1;
+  -webkit-font-smoothing: antialiased;
+  -moz-osx-font-smoothing: grayscale;
+
+
+  &:empty:before {
+    width: 1em;
+    text-align: center;
+    box-sizing: content-box;
+  }
+
+  &.oi-align-center:before {
+    text-align: center;
+  }
+
+  &.oi-align-left:before {
+    text-align: left;
+  }
+
+  &.oi-align-right:before {
+    text-align: right;
+  }
+
+
+  &.oi-flip-horizontal:before {
+    -webkit-transform: scale(-1, 1);
+    -ms-transform: scale(-1, 1);
+    transform: scale(-1, 1);
+  }
+
+  &.oi-flip-vertical:before {
+    -webkit-transform: scale(1, -1);
+    -ms-transform: scale(-1, 1);
+    transform: scale(1, -1);
+  }
+
+  &.oi-flip-horizontal-vertical:before {
+    -webkit-transform: scale(-1, -1);
+    -ms-transform: scale(-1, 1);
+    transform: scale(-1, -1);
+  }
+}
+
+
+
+.oi-account-login:before {
+  content:'\e000';
+}
+
+.oi-account-logout:before {
+  content:'\e001';
+}
+
+.oi-action-redo:before {
+  content:'\e002';
+}
+
+.oi-action-undo:before {
+  content:'\e003';
+}
+
+.oi-align-center:before {
+  content:'\e004';
+}
+
+.oi-align-left:before {
+  content:'\e005';
+}
+
+.oi-align-right:before {
+  content:'\e006';
+}
+
+.oi-aperture:before {
+  content:'\e007';
+}
+
+.oi-arrow-bottom:before {
+  content:'\e008';
+}
+
+.oi-arrow-circle-bottom:before {
+  content:'\e009';
+}
+
+.oi-arrow-circle-left:before {
+  content:'\e00a';
+}
+
+.oi-arrow-circle-right:before {
+  content:'\e00b';
+}
+
+.oi-arrow-circle-top:before {
+  content:'\e00c';
+}
+
+.oi-arrow-left:before {
+  content:'\e00d';
+}
+
+.oi-arrow-right:before {
+  content:'\e00e';
+}
+
+.oi-arrow-thick-bottom:before {
+  content:'\e00f';
+}
+
+.oi-arrow-thick-left:before {
+  content:'\e010';
+}
+
+.oi-arrow-thick-right:before {
+  content:'\e011';
+}
+
+.oi-arrow-thick-top:before {
+  content:'\e012';
+}
+
+.oi-arrow-top:before {
+  content:'\e013';
+}
+
+.oi-audio-spectrum:before {
+  content:'\e014';
+}
+
+.oi-audio:before {
+  content:'\e015';
+}
+
+.oi-badge:before {
+  content:'\e016';
+}
+
+.oi-ban:before {
+  content:'\e017';
+}
+
+.oi-bar-chart:before {
+  content:'\e018';
+}
+
+.oi-basket:before {
+  content:'\e019';
+}
+
+.oi-battery-empty:before {
+  content:'\e01a';
+}
+
+.oi-battery-full:before {
+  content:'\e01b';
+}
+
+.oi-beaker:before {
+  content:'\e01c';
+}
+
+.oi-bell:before {
+  content:'\e01d';
+}
+
+.oi-bluetooth:before {
+  content:'\e01e';
+}
+
+.oi-bold:before {
+  content:'\e01f';
+}
+
+.oi-bolt:before {
+  content:'\e020';
+}
+
+.oi-book:before {
+  content:'\e021';
+}
+
+.oi-bookmark:before {
+  content:'\e022';
+}
+
+.oi-box:before {
+  content:'\e023';
+}
+
+.oi-briefcase:before {
+  content:'\e024';
+}
+
+.oi-british-pound:before {
+  content:'\e025';
+}
+
+.oi-browser:before {
+  content:'\e026';
+}
+
+.oi-brush:before {
+  content:'\e027';
+}
+
+.oi-bug:before {
+  content:'\e028';
+}
+
+.oi-bullhorn:before {
+  content:'\e029';
+}
+
+.oi-calculator:before {
+  content:'\e02a';
+}
+
+.oi-calendar:before {
+  content:'\e02b';
+}
+
+.oi-camera-slr:before {
+  content:'\e02c';
+}
+
+.oi-caret-bottom:before {
+  content:'\e02d';
+}
+
+.oi-caret-left:before {
+  content:'\e02e';
+}
+
+.oi-caret-right:before {
+  content:'\e02f';
+}
+
+.oi-caret-top:before {
+  content:'\e030';
+}
+
+.oi-cart:before {
+  content:'\e031';
+}
+
+.oi-chat:before {
+  content:'\e032';
+}
+
+.oi-check:before {
+  content:'\e033';
+}
+
+.oi-chevron-bottom:before {
+  content:'\e034';
+}
+
+.oi-chevron-left:before {
+  content:'\e035';
+}
+
+.oi-chevron-right:before {
+  content:'\e036';
+}
+
+.oi-chevron-top:before {
+  content:'\e037';
+}
+
+.oi-circle-check:before {
+  content:'\e038';
+}
+
+.oi-circle-x:before {
+  content:'\e039';
+}
+
+.oi-clipboard:before {
+  content:'\e03a';
+}
+
+.oi-clock:before {
+  content:'\e03b';
+}
+
+.oi-cloud-download:before {
+  content:'\e03c';
+}
+
+.oi-cloud-upload:before {
+  content:'\e03d';
+}
+
+.oi-cloud:before {
+  content:'\e03e';
+}
+
+.oi-cloudy:before {
+  content:'\e03f';
+}
+
+.oi-code:before {
+  content:'\e040';
+}
+
+.oi-cog:before {
+  content:'\e041';
+}
+
+.oi-collapse-down:before {
+  content:'\e042';
+}
+
+.oi-collapse-left:before {
+  content:'\e043';
+}
+
+.oi-collapse-right:before {
+  content:'\e044';
+}
+
+.oi-collapse-up:before {
+  content:'\e045';
+}
+
+.oi-command:before {
+  content:'\e046';
+}
+
+.oi-comment-square:before {
+  content:'\e047';
+}
+
+.oi-compass:before {
+  content:'\e048';
+}
+
+.oi-contrast:before {
+  content:'\e049';
+}
+
+.oi-copywriting:before {
+  content:'\e04a';
+}
+
+.oi-credit-card:before {
+  content:'\e04b';
+}
+
+.oi-crop:before {
+  content:'\e04c';
+}
+
+.oi-dashboard:before {
+  content:'\e04d';
+}
+
+.oi-data-transfer-download:before {
+  content:'\e04e';
+}
+
+.oi-data-transfer-upload:before {
+  content:'\e04f';
+}
+
+.oi-delete:before {
+  content:'\e050';
+}
+
+.oi-dial:before {
+  content:'\e051';
+}
+
+.oi-document:before {
+  content:'\e052';
+}
+
+.oi-dollar:before {
+  content:'\e053';
+}
+
+.oi-double-quote-sans-left:before {
+  content:'\e054';
+}
+
+.oi-double-quote-sans-right:before {
+  content:'\e055';
+}
+
+.oi-double-quote-serif-left:before {
+  content:'\e056';
+}
+
+.oi-double-quote-serif-right:before {
+  content:'\e057';
+}
+
+.oi-droplet:before {
+  content:'\e058';
+}
+
+.oi-eject:before {
+  content:'\e059';
+}
+
+.oi-elevator:before {
+  content:'\e05a';
+}
+
+.oi-ellipses:before {
+  content:'\e05b';
+}
+
+.oi-envelope-closed:before {
+  content:'\e05c';
+}
+
+.oi-envelope-open:before {
+  content:'\e05d';
+}
+
+.oi-euro:before {
+  content:'\e05e';
+}
+
+.oi-excerpt:before {
+  content:'\e05f';
+}
+
+.oi-expand-down:before {
+  content:'\e060';
+}
+
+.oi-expand-left:before {
+  content:'\e061';
+}
+
+.oi-expand-right:before {
+  content:'\e062';
+}
+
+.oi-expand-up:before {
+  content:'\e063';
+}
+
+.oi-external-link:before {
+  content:'\e064';
+}
+
+.oi-eye:before {
+  content:'\e065';
+}
+
+.oi-eyedropper:before {
+  content:'\e066';
+}
+
+.oi-file:before {
+  content:'\e067';
+}
+
+.oi-fire:before {
+  content:'\e068';
+}
+
+.oi-flag:before {
+  content:'\e069';
+}
+
+.oi-flash:before {
+  content:'\e06a';
+}
+
+.oi-folder:before {
+  content:'\e06b';
+}
+
+.oi-fork:before {
+  content:'\e06c';
+}
+
+.oi-fullscreen-enter:before {
+  content:'\e06d';
+}
+
+.oi-fullscreen-exit:before {
+  content:'\e06e';
+}
+
+.oi-globe:before {
+  content:'\e06f';
+}
+
+.oi-graph:before {
+  content:'\e070';
+}
+
+.oi-grid-four-up:before {
+  content:'\e071';
+}
+
+.oi-grid-three-up:before {
+  content:'\e072';
+}
+
+.oi-grid-two-up:before {
+  content:'\e073';
+}
+
+.oi-hard-drive:before {
+  content:'\e074';
+}
+
+.oi-header:before {
+  content:'\e075';
+}
+
+.oi-headphones:before {
+  content:'\e076';
+}
+
+.oi-heart:before {
+  content:'\e077';
+}
+
+.oi-home:before {
+  content:'\e078';
+}
+
+.oi-image:before {
+  content:'\e079';
+}
+
+.oi-inbox:before {
+  content:'\e07a';
+}
+
+.oi-infinity:before {
+  content:'\e07b';
+}
+
+.oi-info:before {
+  content:'\e07c';
+}
+
+.oi-italic:before {
+  content:'\e07d';
+}
+
+.oi-justify-center:before {
+  content:'\e07e';
+}
+
+.oi-justify-left:before {
+  content:'\e07f';
+}
+
+.oi-justify-right:before {
+  content:'\e080';
+}
+
+.oi-key:before {
+  content:'\e081';
+}
+
+.oi-laptop:before {
+  content:'\e082';
+}
+
+.oi-layers:before {
+  content:'\e083';
+}
+
+.oi-lightbulb:before {
+  content:'\e084';
+}
+
+.oi-link-broken:before {
+  content:'\e085';
+}
+
+.oi-link-intact:before {
+  content:'\e086';
+}
+
+.oi-list-rich:before {
+  content:'\e087';
+}
+
+.oi-list:before {
+  content:'\e088';
+}
+
+.oi-location:before {
+  content:'\e089';
+}
+
+.oi-lock-locked:before {
+  content:'\e08a';
+}
+
+.oi-lock-unlocked:before {
+  content:'\e08b';
+}
+
+.oi-loop-circular:before {
+  content:'\e08c';
+}
+
+.oi-loop-square:before {
+  content:'\e08d';
+}
+
+.oi-loop:before {
+  content:'\e08e';
+}
+
+.oi-magnifying-glass:before {
+  content:'\e08f';
+}
+
+.oi-map-marker:before {
+  content:'\e090';
+}
+
+.oi-map:before {
+  content:'\e091';
+}
+
+.oi-media-pause:before {
+  content:'\e092';
+}
+
+.oi-media-play:before {
+  content:'\e093';
+}
+
+.oi-media-record:before {
+  content:'\e094';
+}
+
+.oi-media-skip-backward:before {
+  content:'\e095';
+}
+
+.oi-media-skip-forward:before {
+  content:'\e096';
+}
+
+.oi-media-step-backward:before {
+  content:'\e097';
+}
+
+.oi-media-step-forward:before {
+  content:'\e098';
+}
+
+.oi-media-stop:before {
+  content:'\e099';
+}
+
+.oi-medical-cross:before {
+  content:'\e09a';
+}
+
+.oi-menu:before {
+  content:'\e09b';
+}
+
+.oi-microphone:before {
+  content:'\e09c';
+}
+
+.oi-minus:before {
+  content:'\e09d';
+}
+
+.oi-monitor:before {
+  content:'\e09e';
+}
+
+.oi-moon:before {
+  content:'\e09f';
+}
+
+.oi-move:before {
+  content:'\e0a0';
+}
+
+.oi-musical-note:before {
+  content:'\e0a1';
+}
+
+.oi-paperclip:before {
+  content:'\e0a2';
+}
+
+.oi-pencil:before {
+  content:'\e0a3';
+}
+
+.oi-people:before {
+  content:'\e0a4';
+}
+
+.oi-person:before {
+  content:'\e0a5';
+}
+
+.oi-phone:before {
+  content:'\e0a6';
+}
+
+.oi-pie-chart:before {
+  content:'\e0a7';
+}
+
+.oi-pin:before {
+  content:'\e0a8';
+}
+
+.oi-play-circle:before {
+  content:'\e0a9';
+}
+
+.oi-plus:before {
+  content:'\e0aa';
+}
+
+.oi-power-standby:before {
+  content:'\e0ab';
+}
+
+.oi-print:before {
+  content:'\e0ac';
+}
+
+.oi-project:before {
+  content:'\e0ad';
+}
+
+.oi-pulse:before {
+  content:'\e0ae';
+}
+
+.oi-puzzle-piece:before {
+  content:'\e0af';
+}
+
+.oi-question-mark:before {
+  content:'\e0b0';
+}
+
+.oi-rain:before {
+  content:'\e0b1';
+}
+
+.oi-random:before {
+  content:'\e0b2';
+}
+
+.oi-reload:before {
+  content:'\e0b3';
+}
+
+.oi-resize-both:before {
+  content:'\e0b4';
+}
+
+.oi-resize-height:before {
+  content:'\e0b5';
+}
+
+.oi-resize-width:before {
+  content:'\e0b6';
+}
+
+.oi-rss-alt:before {
+  content:'\e0b7';
+}
+
+.oi-rss:before {
+  content:'\e0b8';
+}
+
+.oi-script:before {
+  content:'\e0b9';
+}
+
+.oi-share-boxed:before {
+  content:'\e0ba';
+}
+
+.oi-share:before {
+  content:'\e0bb';
+}
+
+.oi-shield:before {
+  content:'\e0bc';
+}
+
+.oi-signal:before {
+  content:'\e0bd';
+}
+
+.oi-signpost:before {
+  content:'\e0be';
+}
+
+.oi-sort-ascending:before {
+  content:'\e0bf';
+}
+
+.oi-sort-descending:before {
+  content:'\e0c0';
+}
+
+.oi-spreadsheet:before {
+  content:'\e0c1';
+}
+
+.oi-star:before {
+  content:'\e0c2';
+}
+
+.oi-sun:before {
+  content:'\e0c3';
+}
+
+.oi-tablet:before {
+  content:'\e0c4';
+}
+
+.oi-tag:before {
+  content:'\e0c5';
+}
+
+.oi-tags:before {
+  content:'\e0c6';
+}
+
+.oi-target:before {
+  content:'\e0c7';
+}
+
+.oi-task:before {
+  content:'\e0c8';
+}
+
+.oi-terminal:before {
+  content:'\e0c9';
+}
+
+.oi-text:before {
+  content:'\e0ca';
+}
+
+.oi-thumb-down:before {
+  content:'\e0cb';
+}
+
+.oi-thumb-up:before {
+  content:'\e0cc';
+}
+
+.oi-timer:before {
+  content:'\e0cd';
+}
+
+.oi-transfer:before {
+  content:'\e0ce';
+}
+
+.oi-trash:before {
+  content:'\e0cf';
+}
+
+.oi-underline:before {
+  content:'\e0d0';
+}
+
+.oi-vertical-align-bottom:before {
+  content:'\e0d1';
+}
+
+.oi-vertical-align-center:before {
+  content:'\e0d2';
+}
+
+.oi-vertical-align-top:before {
+  content:'\e0d3';
+}
+
+.oi-video:before {
+  content:'\e0d4';
+}
+
+.oi-volume-high:before {
+  content:'\e0d5';
+}
+
+.oi-volume-low:before {
+  content:'\e0d6';
+}
+
+.oi-volume-off:before {
+  content:'\e0d7';
+}
+
+.oi-warning:before {
+  content:'\e0d8';
+}
+
+.oi-wifi:before {
+  content:'\e0d9';
+}
+
+.oi-wrench:before {
+  content:'\e0da';
+}
+
+.oi-x:before {
+  content:'\e0db';
+}
+
+.oi-yen:before {
+  content:'\e0dc';
+}
+
+.oi-zoom-in:before {
+  content:'\e0dd';
+}
+
+.oi-zoom-out:before {
+  content:'\e0de';
+}
diff --git a/src/sass/compass-sass-base/_social.sass b/src/sass/compass-sass-base/_social.sass
new file mode 100644
index 0000000..03dd2b3
--- /dev/null
+++ b/src/sass/compass-sass-base/_social.sass
@@ -0,0 +1,160 @@
+// Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+@import "social/*.png"
+@include all-social-sprites
+
+$socialroundbg: gray !default
+$socialroundhover: lightgray !default
+
+$facebookcolor: #3b5998
+$telegramcolor: #0088D3
+$mailcolor: #004499
+$twittercolor: #1da1f2
+$googlepluscolor: #db4437
+$pinterestcolor: #bd081c
+$instagramcolor: #dddddd
+$youtubecolor: #fb0f21
+$whatsappcolor: #37b12f
+$rsscolor: #f81
+$qrcodecolor: #068
+
+@mixin social-s
+    display: inline-block
+    width: 32px
+    height: 32px
+
+
+@mixin social-m
+    display: inline-block
+    width: 48px
+    height: 48px
+
+
+@mixin social-l
+    display: inline-block
+    width: 64px
+    height: 64px
+
+
+@mixin social-xl
+    display: inline-block
+    width: 128px
+    height: 128px
+
+
+@mixin social-round
+    border-radius: 50%
+    background-color: $socialroundbg
+
+    &:hover
+        background-color: $socialroundhover
+
+
+.social-s
+    @include social-s
+
+
+.social-m
+    @include social-m
+
+
+.social-l
+    @include social-l
+
+
+.social-xl
+    @include social-xl
+
+
+.social-round-s
+    @include social-s
+    @include social-round
+
+
+.social-round-m
+    @include social-m
+    @include social-round
+
+
+.social-round-l
+    @include social-l
+    @include social-round
+
+
+.social-round-xl
+    @include social-xl
+    @include social-round
+
+
+.social-facebook-sw, .social-facebook-mw, .social-facebook-lw, .social-facebook-xlw,
+.social-facebook-sb, .social-facebook-mb, .social-facebook-lb, .social-facebook-xlb
+    &:hover
+        background-color: $facebookcolor
+
+.social-telegram-sw, .social-telegram-mw, .social-telegram-lw, .social-telegram-xlw,
+.social-telegram-sb, .social-telegram-mb, .social-telegram-lb, .social-telegram-xlb
+    &:hover
+        background-color: $telegramcolor
+
+.social-mail-sw, .social-mail-mw, .social-mail-lw, .social-mail-xlw,
+.social-mail-sb, .social-mail-mb, .social-mail-lb, .social-mail-xlb
+    &:hover
+        background-color: $mailcolor
+
+.social-twitter-sw, .social-twitter-mw, .social-twitter-lw, .social-twitter-xlw,
+.social-twitter-sb, .social-twitter-mb, .social-twitter-lb, .social-twitter-xlb
+    &:hover
+        background-color: $twittercolor
+
+.social-googleplus-sw, .social-googleplus-mw, .social-googleplus-lw, .social-googleplus-xlw,
+.social-googleplus-sb, .social-googleplus-mb, .social-googleplus-lb, .social-googleplus-xlb
+    &:hover
+        background-color: $googlepluscolor
+
+.social-pinterest-sw, .social-pinterest-mw, .social-pinterest-lw, .social-pinterest-xlw,
+.social-pinterest-sb, .social-pinterest-mb, .social-pinterest-lb, .social-pinterest-xlb
+    &:hover
+        background-color: $pinterestcolor
+
+.social-instagram-sw, .social-instagram-mw, .social-instagram-lw, .social-instagram-xlw,
+.social-instagram-sb, .social-instagram-mb, .social-instagram-lb, .social-instagram-xlb
+    &:hover
+        background-color: $instagramcolor
+
+.social-youtube-sw, .social-youtube-mw, .social-youtube-lw, .social-youtube-xlw,
+.social-youtube-sb, .social-youtube-mb, .social-youtube-lb, .social-youtube-xlb
+    &:hover
+        background-color: $youtubecolor
+
+.social-whatsapp-sw, .social-whatsapp-mw, .social-whatsapp-lw, .social-whatsapp-xlw,
+.social-whatsapp-sb, .social-whatsapp-mb, .social-whatsapp-lb, .social-whatsapp-xlb
+    &:hover
+        background-color: $whatsappcolor
+
+.social-rss-sw, .social-rss-mw, .social-rss-lw, .social-rss-xlw,
+.social-rss-sb, .social-rss-mb, .social-rss-lb, .social-rss-xlb
+    &:hover
+        background-color: $rsscolor
+
+.social-qrcode-sw, .social-qrcode-mw, .social-qrcode-lw, .social-qrcode-xlw,
+.social-qrcode-sb, .social-qrcode-mb, .social-qrcode-lb, .social-qrcode-xlb
+    &:hover
+        background-color: $qrcodecolor
diff --git a/src/sass/noscript.sass b/src/sass/noscript.sass
new file mode 100644
index 0000000..ff91435
--- /dev/null
+++ b/src/sass/noscript.sass
@@ -0,0 +1,2 @@
+.dropdown:hover > .dropdown-menu
+    display: block
diff --git a/src/sass/screen.sass b/src/sass/screen.sass
new file mode 100644
index 0000000..14ec329
--- /dev/null
+++ b/src/sass/screen.sass
@@ -0,0 +1,369 @@
+// Copyright 2015 Oliver Gutierrez <ogutsua gmail com>
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy of
+// this software and associated documentation files (the "Software"), to deal in
+// the Software without restriction, including without limitation the rights to
+// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
+// of the Software, and to permit persons to whom the Software is furnished to do
+// so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in all
+// copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+// SOFTWARE.
+
+
+$headerbg: #4a86cf
+$headerfg: white
+$highlightbg: #ff3333
+$mainbg: white
+$footerbg: black
+$footerfg: gray
+$socialroundhover: $highlightbg
+
+$left_offcanvas_offset: 270px
+
+@import "compass-sass-base/bootstrap"
+@import "compass-sass-base/base"
+@import "compass-sass-base/social"
+@import "compass-sass-base/animations"
+@import "compass-sass-base/open_iconic_bootstrap"
+
+// Sprites
+@import "website/*.png"
+@include all-website-sprites
+
+body
+    font-family: 'Source Sans Pro', sans-serif
+    font-size: medium
+    background-color: $footerbg
+
+h1, h2, h3, h4, h5, .h1, .h2, .h3, .h4, .h5
+    color: $headerbg
+    margin: 20px 0
+
+blockquote
+    border-left: 3px $headerbg solid
+    background-color: #f0f0f0
+    font-style: italic
+    padding: 20px 30px
+
+table
+    thead
+        th
+            text-align: center
+
+    tr
+        td, th
+            padding: 5px 20px
+            vertical-align: middle !important
+
+    &.schedule
+        td
+            text-align: center
+
+img
+    max-width: 100%
+
+    &.sponsorlogo
+        width: 200px !important
+        max-width: 200px !important
+
+    &[align=right]
+        margin-left: 10px
+
+.btn-website
+    background-color: $headerbg
+    border-radius: 5px
+    font-weight: bold
+    color: $headerfg
+
+    &:hover
+        color: white
+
+.socials
+    a
+        text-decoration: none
+        margin: 0 5px
+
+.post-info
+    time
+        display: inline-block
+    address
+        display: inline-block
+
+.article-socialshare
+    float: right
+
+.thin-text
+    font-weight: 200
+
+#postlist
+    article
+        padding: 30px 0
+
+#socialshare
+    display: inline-block
+    vertical-align: middle
+
+#header
+    background: $headerbg url('../img/skyline.png') no-repeat bottom center
+    color: $headerfg
+    padding: 70px 0
+    background-size: contain
+
+    h1, h2, h3, h4, h5, .h1, .h2, .h3, .h4, .h5
+        color: $headerfg
+
+    .head-title
+        text-align: center
+        padding: 20px 0 70px
+
+    .hero-home
+        text-align: center
+        padding: 20px 0 50px
+
+
+        .h1
+            font-size: 1.5em
+            font-weight: 200
+            margin: 0px
+            padding: 0
+
+            &.guadec
+                font-family: 'Cantarell', sans-serif
+                font-size: 5em
+                font-weight: 500
+                text-transform: uppercase
+                font-weight: bold
+                letter-spacing: -4px
+
+        @media screen and (max-width: 768px)
+            .h1
+                font-size: 1.125em
+
+                &.guadec
+                    font-size: 3.5em
+
+
+    #menubar
+        background-color: $headerbg
+
+        .navbar-toggler
+            color: white !important
+            //border: 1px white solid
+            border: none
+
+        ul
+            li.nav-item
+                font-size: large
+                color: $headerfg
+                margin: 10px
+                font-weight: bold
+
+        .dropdown-menu
+            color: gray
+            background-color: white
+
+            .dropdown-item:hover
+                background-color: #dddddd
+
+            a
+                color: gray
+
+                &:hover
+                    color: gray
+
+        a
+            color: $headerfg
+
+            &:hover
+                color: $headerhover
+
+#content
+    background-color: $mainbg
+    padding-bottom: 20px
+
+    #content-head
+        padding: 15px 0
+
+    .intro-home
+        text-align: center
+        padding: 40px 0
+
+    .sponsors-home
+        text-align: center
+        padding: 40px 0
+
+        a
+            text-decoration: none
+
+            img
+                margin: 20px
+                vertical-align: middle
+
+    .subintro-home
+        text-align: center
+        padding: 40px 0
+
+    .highlights-home
+        padding: 40px 0
+        background-color: #fafafa
+
+        .highlight
+
+            .icon
+                text-align: center
+                font-size: 48px
+                padding: 30px
+                margin: 20px
+                color: white
+                background-color: $headerbg
+                border-radius: 50%
+
+    .news-home
+        padding-top: 30px
+        padding-bottom: 10px
+
+    .news-home-articles
+        padding-bottom: 30px
+
+        .news-article
+            text-align: center
+
+            .h5
+
+                &:after
+                    box-sizing: border-box
+                    content: " "
+                    display: block
+                    margin: 20px auto 15px
+                    width: 35px
+                    border: 2px $headerbg solid
+
+    .social-home
+        padding: 30px
+
+        .socials
+            padding: 20px
+
+#footer
+    padding: 50px 0
+    color: $footerfg
+    background-color: $footerbg
+
+    a
+        color: $footerfg
+
+        &:hover
+            color: $footerhover
+
+    .footlinks
+        ul
+            list-style: none
+            margin: 0
+            padding: 0
+
+            li
+                margin: 5px 0
+
+#cookiesmessage
+    position: fixed
+    bottom: 10px
+    z-index: 10000
+    margin: 30px
+    padding: 30px
+    border-radius: 10px
+    border: 2px $footerfg solid
+    color: $footerfg
+    background-color: $footerbg
+
+    .buttons
+        text-align: center
+        margin-top: 20px
+
+#goup
+    padding: 15px 20px
+    cursor: pointer
+    position: fixed
+    display: none
+    bottom: 10px
+    right: 10px
+    z-index: 10
+    @include animation-zoomin
+
+
+
+// Schedule styling
+
+.schedule
+    font-family: 'Source Sans Pro', sans-serif
+    border-collapse: collapse
+    overflow: auto
+
+    td
+        border: none
+        vertical-align: middle
+        text-align: center
+
+
+    th
+        text-align:left
+        padding: 1ex 2em 1ex 2em
+
+
+    tr.rooms th:not(:first-child)
+        text-align: center
+        border: 1px solid #b6b6b6
+        background-color: #EAECEE
+
+
+    thead tr td
+        width: 45%
+        font-weight: bold
+
+    tbody tr td
+        width: 45%
+        border: 2px solid #fff
+        text-align: center
+        padding: 1ex 2em 1ex 2em
+        overflow: hidden
+
+    tbody tr td span
+        // 80px for header bar (linking), on the span inside
+        // and 1ex for the padding of the cell
+        padding-top: calc(80px + 1ex)
+        margin-top: calc(-80px - 1ex)
+
+    tr > td:first-child
+        width: 10%
+        border: none
+        font-weight: bold
+
+.abstract
+    margin-top: calc(30px - 80px)
+    padding-top: 80px
+    border-bottom: 1px black solid
+    margin-bottom: 20px
+
+    h4
+        font-size: 1.5em
+
+
+    .details
+        font-style: italic
+        font-weight: bold
+        color: gray
+
+
+.talk
+    background-color: #efefef
+
+.break
+    background-color: #dadada



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]