<!doctype html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
  <title>GBForth</title>
  <style type="text/css">
    body {
  font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
  color: #222;
  font-size: 100%;
}

.slide {
  position: absolute;
  top: 0; bottom: 0;
  left: 0; right: 0;
  background-color: #f7f7f7;
}

.slide-content {
  width: 800px;
  height: 600px;
  overflow: hidden;
  margin: 80px auto 0 auto;
  padding: 30px;

  font-weight: 200;
  font-size: 200%;
  line-height: 1.375;
}

.controls {
  position: absolute;
  bottom: 20px;
  left: 20px;
}

.arrow {
  width: 0; height: 0;
  border: 30px solid #333;
  float: left;
  margin-right: 30px;

  -webkit-touch-callout: none;
  -webkit-user-select: none;
  -khtml-user-select: none;
  -moz-user-select: none;
  -ms-user-select: none;
  user-select: none;
}

.prev {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-left-color: transparent;

  border-left-width: 0;
  border-right-width: 50px;
}

.next {
  border-top-color: transparent;
  border-bottom-color: transparent;
  border-right-color: transparent;

  border-left-width: 50px;
  border-right-width: 0;
}

.prev:hover {
  border-right-color: #888;
  cursor: pointer;
}

.next:hover {
  border-left-color: #888;
  cursor: pointer;
}

h1 {
  font-size: 300%;
  line-height: 1.2;
  text-align: center;
  margin: 170px 0 0;
}

h2 {
  font-size: 100%;
  line-height: 1.2;
  margin: 5px 0;
  text-align: center;
  font-weight: 200;
}

h3 {
  font-size: 140%;
  line-height: 1.2;
  border-bottom: 1px solid #aaa;
  margin: 0;
  padding-bottom: 15px;
}

ul {
  padding: 20px 0 0 60px;
  font-weight: 200;
  line-height: 1.375;
}

.author h1 {
  font-size: 170%;
  font-weight: 200;
  text-align: center;
  margin-bottom: 30px;
}

.author h3 {
  font-weight: 100;
  text-align: center;
  font-size: 95%;
  border: none;
}

a {
  text-decoration: none;
  color: #44a4dd;
}

a:hover {
  color: #66b5ff;
}

pre {
  font-size: 60%;
  line-height: 1.3;
}

.progress {
  position: fixed;
  top: 0; left: 0; right: 0;
  height: 3px;
  z-index: 1;
}

.progress-bar {
  width: 0%;
  height: 3px;
  background-color: #b4b4b4;

  -webkit-transition: width 0.05s ease-out;
  -moz-transition: width 0.05s ease-out;
  -o-transition: width 0.05s ease-out;
  transition: width 0.05s ease-out;
}

.hidden {
  display: none;
}

@media (max-width: 850px) {

  body {
    font-size: 70%;
  }

  .slide-content {
    width: auto;
  }

  img {
    width: 100%;
  }

  h1 {
    margin-top: 120px;
  }

  .prev, .prev:hover {
    border-right-color: rgba(135, 135, 135, 0.5);
  }

  .next, .next:hover {
    border-left-color: rgba(135, 135, 135, 0.5);
  }
}

@media (max-width: 480px) {
  body {
    font-size: 50%;
    overflow: hidden;
  }

  .slide-content {
    padding: 10px;
    margin-top: 10px;
    height: 340px;
  }

  h1 {
    margin-top: 50px;
  }

  ul {
    padding-left: 25px;
  }
}

@media print {
  * {
    -webkit-print-color-adjust: exact;
  }

  @page {
    size: letter;
  }

  .hidden {
    display: inline;
  }

  html {
    width: 100%;
    height: 100%;
    overflow: visible;
  }

  body {
    margin: 0 auto !important;
    border: 0;
    padding: 0;
    float: none !important;
    overflow: visible;
    background: none !important;
    font-size: 52%;
  }

  .progress, .controls {
    display: none;
  }

  .slide {
    position: static;
  }

  .slide-content {
    border: 1px solid #222;
    margin-top: 0;
    margin-bottom: 40px;
    height: 3.5in;
    overflow: visible;
  }

  .slide:nth-child(even) {
    /* 2 slides per page */
    page-break-before: always;
  }
}

/*

github.com style (c) Vasily Polovnyov <vast@whiteants.net>

*/

.hljs {
  display: block;
  overflow-x: auto;
  padding: 0.5em;
  color: #333;
  background: #f8f8f8;
}

.hljs-comment,
.hljs-quote {
  color: #998;
  font-style: italic;
}

.hljs-keyword,
.hljs-selector-tag,
.hljs-subst {
  color: #333;
  font-weight: bold;
}

.hljs-number,
.hljs-literal,
.hljs-variable,
.hljs-template-variable,
.hljs-tag .hljs-attr {
  color: #008080;
}

.hljs-string,
.hljs-doctag {
  color: #d14;
}

.hljs-title,
.hljs-section,
.hljs-selector-id {
  color: #900;
  font-weight: bold;
}

.hljs-subst {
  font-weight: normal;
}

.hljs-type,
.hljs-class .hljs-title {
  color: #458;
  font-weight: bold;
}

.hljs-tag,
.hljs-name,
.hljs-attribute {
  color: #000080;
  font-weight: normal;
}

.hljs-regexp,
.hljs-link {
  color: #009926;
}

.hljs-symbol,
.hljs-bullet {
  color: #990073;
}

.hljs-built_in,
.hljs-builtin-name {
  color: #0086b3;
}

.hljs-meta {
  color: #999;
  font-weight: bold;
}

.hljs-deletion {
  background: #fdd;
}

.hljs-addition {
  background: #dfd;
}

.hljs-emphasis {
  font-style: italic;
}

.hljs-strong {
  font-weight: bold;
}

@import url(https://fonts.googleapis.com/css?family=Open+Sans:400,700,300);

body {
    -webkit-font-smoothing: antialiased;
    text-rendering: optimizelegibility;
    background-color: #FFFFFF;
    color: #242731;
    font-family: "Open Sans", sans-serif;
    font-size: 1em;
}

.slide {
    overflow: hidden;
}
.slide-content {
    overflow: visible;
}

#slide-1 h1, .dark h1 {
  margin: 170px 0 0;
}

h1 {
    font-size: 250%;
    margin: auto;
}

h1, h2, h3, h4, h5, h6 {
    font-weight: 700;
    letter-spacing: -0.5px;
}

h1, h2, h3 {
    color: #FF5544;
}

h3 {
  border-bottom: 1px solid rgba(36,39,49,.4);
}

h4, h5 {
    color: #000000;
    margin-bottom: 0;
}

h6 {
    margin-bottom: 0;
    text-transform: uppercase;
}

h4 + p, h5 + p, h6 + p,
h4 + ul, h5 + ul, h6 + ul {
    margin-top: 0;
}

a {
    color: #61C5AA;
    text-decoration: underline;
}

a:hover {
    color: #44b999;
    text-decoration: none;
}

ul {
    list-style: none;
}
ul > li {
    margin: -0.2em 0;
}
ul > li:before {
    content: "";
    border-color: transparent rgba(36,39,49,.4);
    border-style: solid;
    border-width: 0.2em 0 0.2em 0.3em;
    display: block;
    left: -0.6em;
    top: 0.95em;
    position: relative;
    margin: 0px;
    padding: 0px;
    height: 0px;
    width: 0px;
}

li > ul, li > ol {
    padding: 0 0 0 1.5em;
}

li > ul > li:before {
    opacity: 0.5;
}

pre, code {
    font-family: "Monaco", monospace;
}

p > code, li > code {
    color: #FF5544;
    background-color: #FFFFFF;
    padding: 0.2em 0.4em;
    font-size: 60%;
    border: 1px solid rgba(0, 0, 0, 0.1);
}

pre, blockquote, img {
    padding: 1em;
    background-color: #FFFFFF;
    box-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
}

img {
    padding: 0.5em;
    display: block;
    margin-left: auto;
    margin-right: auto;
    width: 100%;
}

img + em {
    display: block;
    margin-top: 0.5em;
    text-align: center;
    font-size: 50%;
}

blockquote > p:first-child {
    margin-top: 0;
}

blockquote > p:last-child {
    margin-bottom: 0;
}

blockquote {
    border-left: 3px solid #FF5544;
}

img[alt="background"] {
    padding: 0;
    margin: 0;
    box-shadow: none;
    position: absolute;
    z-index: 5;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    object-fit: cover;
    opacity: 0.05;
}

#slide-1 img[alt="background"] {
  opacity: 0.08;
}

#slide-1 {
    background-color: #FF5544;
    color: #FFFFFF;
}


.slide.dark {
    background-color: #222222;
    color: #FFFFFF;
}

#slide-1 h1, #slide-1 h2,
.slide.dark h1, .slide.dark h2 {
    color: #FFFFFF;
    text-shadow: 0px 1px 1px rgba(0, 0, 0, 0.2);
    position: relative;
    z-index: 10;
}

#slide-1 h2, .slide.dark h2 {
    opacity: 0.75;
}

.slide.dark ul > li:before {
    border-color: transparent rgba(255,255,255,.6);
}

.author-slide {
    background-color: #737373;
}

.author-slide h1 {
    color: #FFFFFF;
}

.author-slide, .slide.dark a {
    color: #FF5544;
    position: relative;
    z-index: 10;
}

.progress {
    z-index: 100;
}
.progress-bar {
    background-color: #FF5544;
    transition-duration: 0.25s;
}

  </style>
</head>
<body>
    <div class="progress">
    <div class="progress-bar"></div>
  </div>

  <div class="slide" id="slide-1">
    <section class="slide-content"><h1 id="gbforth">GBForth</h1>
<h2 id="a-forth-based-game-boy-development-kit">A Forth-based Game Boy development kit</h2>
<p><img src="gbschematic.jpg" alt="background"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-2">
    <section class="slide-content"><h3 id="game-boy-hardware">Game Boy hardware</h3>
<ul>
<li>8-bit CPU</li>
<li>4 MHz (~1M instructions)</li>
<li>32kB ROM (of which 16 bankable)</li>
<li>4kB RAM</li>
<li>Cartridge contains data + hardware</li>
</ul>
<p><img src="memmap.gif" alt="memmap">
<em><span style="color: #EB3223">ROM</span>
<span style="background-color: #72FBFD">Tile RAM</span>
<span style="color: #0022F5;">BG Map</span>
<span style="background-color: #FFFD54;">RAM</span>
<span style="color: #CC36D8">OAM</span></em></p>
</section>
  </div>
  <div class="slide hidden" id="slide-3">
    <section class="slide-content"><p><img src="draw.png" alt="draw"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-4">
    <section class="slide-content"><h3 id="forth">Forth</h3>
<ul>
<li>Stack based</li>
<li>Concatenative</li>
</ul>
<pre><code class="lang-fs">: INC
  <span class="hljs-number">1</span> + ;
</code></pre>
<p>Only <strong>numbers</strong> and <strong>words</strong>:</p>
<pre><code>1   →   PUSH 1
+   →   CALL +
</code></pre></section>
  </div>
  <div class="slide hidden" id="slide-5">
    <section class="slide-content"><h1 id="approaches-we-considered">Approaches we considered</h1>
<ul>
<li>Read docs about GB</li>
<li>Start writing a compiler</li>
<li>...wait forever until you get something on the screen</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-6">
    <section class="slide-content"><h1 id="however-">However...</h1>
<ul>
<li>Not incremental</li>
<li>Long feedback cycle</li>
</ul>
<h1 id="-">😕</h1>
</section>
  </div>
  <div class="slide hidden" id="slide-7">
    <section class="slide-content"><h1 id="our-approach-">Our approach ✨</h1>
<ul>
<li>Start with working game (binary)</li>
<li>Make Forth emit those bytes</li>
<li>Reverse engineer + refactor bytes<ul>
<li>Add abstractions</li>
<li>Build libraries</li>
</ul>
</li>
<li>Forth compiler → GB binary</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-8">
    <section class="slide-content"><p><img src="helloworld.png" alt="helloworld"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-9">
    <section class="slide-content"><h2 id="reverse-engineer-binary-to-assembly">Reverse-engineer binary to assembly</h2>
<pre><code>$00  $c3  $50  $01  $ce  $ed  $66  $66
$cc  $0d  $00  $0b  $03  $73  $00  $83
$00  $0c  $00  $0d  $00  $08  $11  $1f
$88  $89  $00  $0e  $dc  $cc  $6e  $e6
$dd  $dd  $d9  $99  $bb  $bb  $67  $63
$6e  $0e  $ec  $cc  $dd  $dc  $99  $9f
$bb  $b9  $33  $3e  $45  $58  $41  $4d
$50  $4c  $45  $00  $00  $00  $00  $00
$00  $00  $00  $00  $00  $00  $00  $00
$00  $00  $01  $33
</code></pre></section>
  </div>
  <div class="slide hidden" id="slide-10">
    <section class="slide-content"><h2 id="make-program-that-emits-bytes">Make program that emits bytes</h2>
<pre><code>$00 c, $c3 c, $50 c, $01 c, $ce c, $ed c, $66 c, $66 c,
$cc c, $0d c, $00 c, $0b c, $03 c, $73 c, $00 c, $83 c,
$00 c, $0c c, $00 c, $0d c, $00 c, $08 c, $11 c, $1f c,
$88 c, $89 c, $00 c, $0e c, $dc c, $cc c, $6e c, $e6 c,
$dd c, $dd c, $d9 c, $99 c, $bb c, $bb c, $67 c, $63 c,
$6e c, $0e c, $ec c, $cc c, $dd c, $dc c, $99 c, $9f c,
$bb c, $b9 c, $33 c, $3e c, $45 c, $58 c, $41 c, $4d c,
$50 c, $4c c, $45 c, $00 c, $00 c, $00 c, $00 c, $00 c,
$00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c,
$00 c, $00 c, $01 c, $33 c,
</code></pre></section>
  </div>
  <div class="slide hidden" id="slide-11">
    <section class="slide-content"><h2 id="find-the-patterns-and-meaning">Find the patterns and meaning</h2>
<pre>
$00 c, $c3 c, $50 c, $01 c, <span style="color: #AA00AA">$ce c, $ed c, $66 c, $66 c,
$cc c, $0d c, $00 c, $0b c, $03 c, $73 c, $00 c, $83 c,
$00 c, $0c c, $00 c, $0d c, $00 c, $08 c, $11 c, $1f c,
$88 c, $89 c, $00 c, $0e c, $dc c, $cc c, $6e c, $e6 c,
$dd c, $dd c, $d9 c, $99 c, $bb c, $bb c, $67 c, $63 c,
$6e c, $0e c, $ec c, $cc c, $dd c, $dc c, $99 c, $9f c,
$bb c, $b9 c, $33 c, $3e c,</span> <span style="color: #00AA00">$45 c, $58 c, $41 c, $4d c,
$50 c, $4c c, $45 c, $00 c, $00 c, $00 c, $00 c, $00 c,
$00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c,</span>
$00 c, $00 c, $01 c, $33 c,
</pre></section>
  </div>
  <div class="slide hidden" id="slide-12">
    <section class="slide-content"><h2 id="extract-patterns-into-definitions">Extract patterns into definitions</h2>
<pre>
<span style="color: #AA00AA">: logo
  $ce c, $ed c, $66 c, $66 c, $cc c, $0d c, $00 c, $0b c,
  $03 c, $73 c, $00 c, $83 c, $00 c, $0c c, $00 c, $0d c,
  $00 c, $08 c, $11 c, $1f c, $88 c, $89 c, $00 c, $0e c,
  $dc c, $cc c, $6e c, $e6 c, $dd c, $dd c, $d9 c, $99 c,
  $bb c, $bb c, $67 c, $63 c, $6e c, $0e c, $ec c, $cc c,
  $dd c, $dc c, $99 c, $9f c, $bb c, $b9 c, $33 c, $3e c, ;</span>

<span style="color: #00AA00">: title
  $45 c, $58 c, $41 c, $4d c, $50 c, $4c c, $45 c, $00 c,
  $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, $00 c, ;</span>

$00 c, $c3 c, $50 c, $01 c,
<span style="color: #AA00AA">logo</span>
<span style="color: #00AA00">title</span>
$00 c, $00 c, $01 c, $33 c,

</pre></section>
  </div>
  <div class="slide hidden" id="slide-13">
    <section class="slide-content"><h2 id="implement-assembler">Implement assembler</h2>
<p><img src="asm.png" alt="asm"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-14">
    <section class="slide-content"><h2 id="full-forth-assembler-game">Full Forth Assembler &quot;game&quot;</h2>
<pre>
<span style="color: #00AA00">title: EXAMPLE</span>

$150 ==>
main:

di,
$ffff # sp ld,

%11100100 # a ld,

a [rGBP] ld,

0 # a ld,
a [rSCX] ld,
a [rSCY] ld,

<span style="color: #777777">( ... )</span>
</pre></section>
  </div>
  <div class="slide hidden" id="slide-15">
    <section class="slide-content"><p><img src="helloworld.png" alt="helloworld"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-16">
    <section class="slide-content"><p><img src="helloreaktor.jpg" alt="helloreaktor"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-17">
    <section class="slide-content"><h1 id="now-what-">Now what? 🤔</h1>
<h2 id="implementing-forth">Implementing Forth</h2>
<ul>
<li>Break binary compatibility</li>
<li>New testing strategy<ul>
<li>Unit tests</li>
<li>Visual comparison</li>
<li>Using emulator for automated testing</li>
</ul>
</li>
<li>Rewriting <em>Hello World</em> to Forth</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-18">
    <section class="slide-content"><h3 id="implementing-forth">Implementing Forth</h3>
<ul>
<li>Add a compiler</li>
<li>Implement code primitives</li>
<li>Adding libraries</li>
<li>Replacing ASM with Forth</li>
</ul>
</section>
  </div>
  <div class="slide hidden" id="slide-19">
    <section class="slide-content"><p><img src="forth.png" alt="forth"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-20">
    <section class="slide-content"><h1 id="the-final-test-">The final test 💪</h1>
<h2 id="compiling-a-third-party-forth-game-">Compiling a third party Forth game...</h2>
<h2 id="">&nbsp;</h2>
<pre><code class="lang-fs">\ sokoban - a maze game <span class="hljs-keyword">in</span> FORTH

\ Copyright (C) <span class="hljs-number">1995</span>,<span class="hljs-number">1997</span>,<span class="hljs-number">1998</span>,<span class="hljs-number">2003</span>,<span class="hljs-number">2007</span>,<span class="hljs-number">2012</span>,<span class="hljs-number">2013</span>,<span class="hljs-number">2015</span>
\ Free Software Foundation, Inc.

\ This file is part <span class="hljs-keyword">of</span> Gforth.

<span class="hljs-number">40</span> Constant /maze  \ maximal maze line

Create maze  <span class="hljs-number">1</span> cells allot /maze <span class="hljs-number">25</span> * allot  \ current maze
Variable mazes   <span class="hljs-number">0</span> mazes !  \ root pointer
Variable soko    <span class="hljs-number">0</span> soko !   \ player position
Variable &gt;maze   <span class="hljs-number">0</span> &gt;maze !  \ current compiled maze

: maze-field ( -- addr n )
    maze dup cell+ swap @ chars ;

: .score ( -- )
    .<span class="hljs-string">" Level: "</span> level# @ <span class="hljs-number">2</span> .r .<span class="hljs-string">"  Score: "</span> score @ <span class="hljs-number">4</span> .r
    .<span class="hljs-string">"  Moves: "</span> moves @ <span class="hljs-number">6</span> .r .<span class="hljs-string">"  Rocks: "</span> rocks @ <span class="hljs-number">2</span> .r ;

: .maze ( -- )  \ display maze
    <span class="hljs-number">0</span> <span class="hljs-number">0</span> at-xy  .score
    cr  maze-field over + swap
    DO  I /maze <span class="hljs-class"><span class="hljs-keyword">type</span> <span class="hljs-title">cr</span>  /<span class="hljs-title">maze</span> <span class="hljs-title">chars</span>  +<span class="hljs-title">LOOP</span> ;</span>
</code></pre>
</section>
  </div>
  <div class="slide hidden" id="slide-21">
    <section class="slide-content"><p><img src="tweet1.png" alt="tweet1"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-22">
    <section class="slide-content"><p><img src="tweet2.png" alt="tweet2"></p>
</section>
  </div>
  <div class="slide hidden" id="slide-23">
    <section class="slide-content"><h3 id="future-development-">Future development 🚀</h3>
<ul>
<li>ASM bug fixes</li>
<li>Compiler optimisations</li>
<li>GB Color support</li>
<li>Declaritive RAM initialisation</li>
<li>Automatic ROM bank switching</li>
<li>Debugging tools</li>
<li><strong>Actually writing a game</strong></li>
<li>...</li>
</ul>
</section>
  </div>
  <div class="slide hidden  dark" id="slide-24">
    <section class="slide-content"><h1 id="-more-">🤓 More?</h1>
<ul>
<li><a href="https://ams-hackers.github.io/gbforth">ams-hackers/gbforth</a></li>
<li><a href="https://www.youtube.com/watch?v=HyzD8pNlpwI">The Ultimate Game Boy Talk (33c3)</a></li>
<li>Join <strong>#amsterdam-hacking</strong></li>
</ul>
<p><img src="gbschematic2.jpg" alt="background"></p>
</section>
  </div>



  <script type="text/javascript">
    /**
 * Returns the current page number of the presentation.
 */
function currentPosition() {
  return parseInt(document.querySelector('.slide:not(.hidden)').id.slice(6));
}


/**
 * Navigates forward n pages
 * If n is negative, we will navigate in reverse
 */
function navigate(n) {
  var position = currentPosition();
  var numSlides = document.getElementsByClassName('slide').length;

  /* Positions are 1-indexed, so we need to add and subtract 1 */
  var nextPosition = (position - 1 + n) % numSlides + 1;

  /* Normalize nextPosition in-case of a negative modulo result */
  nextPosition = (nextPosition - 1 + numSlides) % numSlides + 1;

  document.getElementById('slide-' + position).classList.add('hidden');
  document.getElementById('slide-' + nextPosition).classList.remove('hidden');

  updateProgress();
  updateURL();
  updateTabIndex();
}


/**
 * Updates the current URL to include a hashtag of the current page number.
 */
function updateURL() {
  try {
    window.history.replaceState({} , null, '#' + currentPosition());
  } catch (e) {
    window.location.hash = currentPosition();
  }
}


/**
 * Sets the progress indicator.
 */
function updateProgress() {
  var progressBar = document.querySelector('.progress-bar');

  if (progressBar !== null) {
    var numSlides = document.getElementsByClassName('slide').length;
    var position = currentPosition() - 1;
    var percent = (numSlides === 1) ? 100 : 100 * position / (numSlides - 1);
    progressBar.style.width = percent.toString() + '%';
  }
}


/**
 * Removes tabindex property from all links on the current slide, sets
 * tabindex = -1 for all links on other slides. Prevents slides from appearing
 * out of control.
 */
function updateTabIndex() {
  var allLinks = document.querySelectorAll('.slide a');
  var position = currentPosition();
  var currentPageLinks = document.getElementById('slide-' + position).querySelectorAll('a');
  var i;

  for (i = 0; i < allLinks.length; i++) {
    allLinks[i].setAttribute('tabindex', -1);
  }

  for (i = 0; i < currentPageLinks.length; i++) {
    currentPageLinks[i].removeAttribute('tabindex');
  }
}

/**
 * Determines whether or not we are currently in full screen mode
 */
function isFullScreen() {
  return document.fullscreenElement ||
         document.mozFullScreenElement ||
         document.webkitFullscreenElement ||
         document.msFullscreenElement;
}

/**
 * Toggle fullScreen mode on document element.
 * Works on chrome (>= 15), firefox (>= 9), ie (>= 11), opera(>= 12.1), safari (>= 5).
 */
function toggleFullScreen() {
  /* Convenient renames */
  var docElem = document.documentElement;
  var doc = document;

  docElem.requestFullscreen =
      docElem.requestFullscreen ||
      docElem.msRequestFullscreen ||
      docElem.mozRequestFullScreen ||
      docElem.webkitRequestFullscreen.bind(docElem, Element.ALLOW_KEYBOARD_INPUT);

  doc.exitFullscreen =
      doc.exitFullscreen ||
      doc.msExitFullscreen ||
      doc.mozCancelFullScreen ||
      doc.webkitExitFullscreen;

  isFullScreen() ? doc.exitFullscreen() : docElem.requestFullscreen();
}

document.addEventListener('DOMContentLoaded', function () {
  // Update the tabindex to prevent weird slide transitioning
  updateTabIndex();

  // If the location hash specifies a page number, go to it.
  var page = window.location.hash.slice(1);
  if (page) {
    navigate(parseInt(page) - 1);
  }

  document.onkeydown = function (e) {
    var kc = e.keyCode;

    // left, down, H, J, backspace, PgUp - BACK
    // up, right, K, L, space, PgDn - FORWARD
    // enter - FULLSCREEN
    if (kc === 37 || kc === 40 || kc === 8 || kc === 72 || kc === 74 || kc === 33) {
      navigate(-1);
    } else if (kc === 38 || kc === 39 || kc === 32 || kc === 75 || kc === 76 || kc === 34) {
      navigate(1);
    } else if (kc === 13) {
      toggleFullScreen();
    }
  };

  if (document.querySelector('.next') && document.querySelector('.prev')) {
    document.querySelector('.next').onclick = function (e) {
      e.preventDefault();
      navigate(1);
    };

    document.querySelector('.prev').onclick = function (e) {
      e.preventDefault();
      navigate(-1);
    };
  }
});


  </script>
</body>
</html>