[
  {
    "path": ".gitignore",
    "content": ".DS_Store\nnode_modules\nbower_components\ncoverage\n"
  },
  {
    "path": ".jshintrc",
    "content": "{\n  \"bitwise\": false,\n  \"curly\": true,\n  \"eqeqeq\": true,\n  \"expr\": true,\n  \"forin\": true,\n  \"freeze\": true,\n  \"funcscope\": true,\n  \"globalstrict\": true,\n  \"nonbsp\": true,\n  \"unused\": true,\n  \"debug\": true,\n  \"evil\": true,\n  \"lastsemic\": true,\n  \"loopfunc\": true,\n  \"proto\": true,\n  \"scripturl\": true,\n  \"strict\": true,\n  \"browser\": true,\n  \"browserify\": true,\n  \"node\": true\n}\n"
  },
  {
    "path": ".travis.yml",
    "content": "language: node_js\nnode_js:\n  - 6.9.1\n# Send coverage data to Coveralls\nafter_script: \"cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js\"\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "# Contributing\n\n## Code style\nRegarding code style like indentation and whitespace, **follow the conventions you see used in the source already.**\n\n## Modifying the code\n\nPlease don't edit `/dist/slideout.js` and `/dist/slideout.min.js` files. You'll find source code in the `index.js` file.\n\n1. Fork and clone the repo.\n2. Run `npm install` to install all dependencies.\n3. Create a new branch, please don't work in your `master` branch directly.\n4. Open the file `/test/index.html`.\n5. Code!\n\n### Running the tests\n\n- Run `npm test` from your command line and check the console\n- Open the `/test/index.html` file to run test in your browser.\n\n## Pull requests\n\n1. Create a new branch, **please don't work in your `master` branch directly**.\n2. Code!\n3. Update the tests and run `npm test` to see the tests.\n4. Run `npm run hint`.\n5. Run `npm run dist` to build a new version.\n6. Update the documentation and package to reflect any changes.\n7. Push to your fork and submit a pull request."
  },
  {
    "path": "LICENSE",
    "content": "The MIT License (MIT)\n\nCopyright (c) 2015 Mango\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n\n"
  },
  {
    "path": "README.md",
    "content": "# Slideout.js\n\n[![NPM version][npm-image]][npm-link] [![License][lic-image]][npm-link] [![Build status][travis-image]][travis-link] [![Coverage Status][coverage-image]][coverage-link] [![Dependency status][deps-image]][deps-link] [![devDependency status][devdeps-image]][devdeps-link] [![downloads][dt-image]][npm-link]\n\n> A touch slideout navigation menu for your mobile web apps.\n\n## Features\n\n- Dependency-free.\n- Simple markup.\n- Native scrolling.\n- Easy customization.\n- CSS transforms & transitions.\n- Just 2 Kb! (min & gzip)\n\n## Demo\n\n[Check out the demo](https://mango.github.io/slideout/) to see it in action (on your mobile or emulate touches on your browser).\n\n<img src=\"https://i.imgur.com/AWgwlVW.gif\" alt=\"Slideout.js demo\">\n\n## Installation\n\nSlideout is available on cdnjs\n\n```html\n<script src=\"https://cdnjs.cloudflare.com/ajax/libs/slideout/1.0.1/slideout.min.js\"></script>\n```\n\nAlso you can use one of many package managers\n\n    $ npm install slideout\n\n    $ spm install slideout\n\n    $ bower install slideout.js\n\n    $ component install mango/slideout\n\n## Usage\n\nImplementing Slideout.js into your project is easy.\n\nFirst of all, you'll need to create your markup. You should have a menu (`#menu`) and a main content (`#panel`) into your body.\n\n```html\n<nav id=\"menu\">\n  <header>\n    <h2>Menu</h2>\n  </header>\n</nav>\n\n<main id=\"panel\">\n  <header>\n    <h2>Panel</h2>\n  </header>\n</main>\n```\n\nAdd the Slideout.js styles (index.css) in your web application.\n\n```css\nbody {\n  width: 100%;\n  height: 100%;\n}\n\n.slideout-menu {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  width: 256px;\n  min-height: 100vh;\n  overflow-y: scroll;\n  -webkit-overflow-scrolling: touch;\n  z-index: 0;\n  display: none;\n}\n\n.slideout-menu-left {\n  left: 0;\n}\n\n.slideout-menu-right {\n  right: 0;\n}\n\n.slideout-panel {\n  position: relative;\n  z-index: 1;\n  will-change: transform;\n  background-color: #FFF; /* A background-color is required */\n  min-height: 100vh;\n}\n\n.slideout-open,\n.slideout-open body,\n.slideout-open .slideout-panel {\n  overflow: hidden;\n}\n\n.slideout-open .slideout-menu {\n  display: block;\n}\n```\n\nThen you just include Slideout.js, create a new instance with some options and call the toggle method:\n\n```html\n<script src=\"dist/slideout.min.js\"></script>\n<script>\n  var slideout = new Slideout({\n    'panel': document.getElementById('panel'),\n    'menu': document.getElementById('menu'),\n    'padding': 256,\n    'tolerance': 70\n  });\n\n  // Toggle button\n  document.querySelector('.toggle-button').addEventListener('click', function() {\n    slideout.toggle();\n  });\n</script>\n```\n\n#### Full example\n\n```html\n<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\">\n    <title>Slideout Demo</title>\n    <meta http-equiv=\"cleartype\" content=\"on\">\n    <meta name=\"MobileOptimized\" content=\"320\">\n    <meta name=\"HandheldFriendly\" content=\"True\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n    <style>\n      body {\n        width: 100%;\n        height: 100%;\n      }\n\n      .slideout-menu {\n        position: fixed;\n        left: 0;\n        top: 0;\n        bottom: 0;\n        right: 0;\n        z-index: 0;\n        width: 256px;\n        overflow-y: scroll;\n        -webkit-overflow-scrolling: touch;\n        display: none;\n      }\n\n      .slideout-panel {\n        position: relative;\n        z-index: 1;\n        will-change: transform;\n      }\n\n      .slideout-open,\n      .slideout-open body,\n      .slideout-open .slideout-panel {\n        overflow: hidden;\n      }\n\n      .slideout-open .slideout-menu {\n        display: block;\n      }\n    </style>\n  </head>\n  <body>\n\n    <nav id=\"menu\">\n      <h2>Menu</h2>\n    </nav>\n\n    <main id=\"panel\">\n      <header>\n        <button class=\"toggle-button\">☰</button>\n        <h2>Panel</h2>\n      </header>\n    </main>\n\n    <script src=\"dist/slideout.min.js\"></script>\n    <script>\n      var slideout = new Slideout({\n        'panel': document.getElementById('panel'),\n        'menu': document.getElementById('menu'),\n        'padding': 256,\n        'tolerance': 70\n      });\n\n      // Toggle button\n      document.querySelector('.toggle-button').addEventListener('click', function() {\n        slideout.toggle();\n      });\n    </script>\n\n  </body>\n</html>\n```\n\n## Browser Support\n\n- Chrome (IOS, Android, desktop)\n- Firefox (Android, desktop)\n- Safari (IOS, Android, desktop)\n- Opera (desktop)\n- IE 10+ (desktop and mobile)\n\n## API\n\n### Slideout(options)\nCreate a new instance of `Slideout`.\n\n- `options` (Object) - Options to customize a new instance of Slideout.\n- `options.panel` (HTMLElement) - The DOM element that contains all your application content (`.slideout-panel`).\n- `options.menu` (HTMLElement) - The DOM element that contains your menu application (`.slideout-menu`).\n- `[options.duration]` (Number) - The time (milliseconds) to open/close the slideout. Default: `300`.\n- `[options.easing]` (String) - The CSS effect to use when animating the opening and closing of the slideout. Default: `ease`. Possible values:\n    - `ease`\n    - `linear`\n    - `ease-in`\n    - `ease-out`\n    - `ease-in-out`\n    - `step-start`\n    - `step-end`\n    - [`cubic-bezier`](http://cubic-bezier.com/)\n- `[options.padding]` (Number) - Default: `256`.\n- `[options.tolerance]` (Number) - The number of `px` needed for the menu can be opened completely, otherwise it closes. Default: `70`.\n- `[options.touch]` (Boolean) - Set this option to false to disable Slideout touch events. Default: `true`.\n- `[options.side]` (String) - The side to open the slideout (`left` or `right`). Default: `left`.\n\n```js\nvar slideout = new Slideout({\n  'panel': document.getElementById('main'),\n  'menu': document.getElementById('menu'),\n  'padding': 256,\n  'tolerance': 70,\n  'easing': 'cubic-bezier(.32,2,.55,.27)'\n});\n```\n\n### Slideout.open();\nOpens the slideout menu. It emits `beforeopen` and `open` events.\n\n```js\nslideout.open();\n```\n\n### Slideout.close();\nCloses the slideout menu. It emits `beforeclose` and `close` events.\n\n```js\nslideout.close();\n```\n\n### Slideout.toggle();\nToggles (open/close) the slideout menu.\n\n```js\nslideout.toggle();\n```\n\n### Slideout.isOpen();\nReturns `true` if the slideout is currently open, and `false` if it is closed.\n\n```js\nslideout.isOpen(); // true or false\n```\n\n### Slideout.destroy();\nCleans up the instance so another slideout can be created on the same area.\n\n```js\nslideout.destroy();\n```\n\n### Slideout.enableTouch();\nEnables opening the slideout via touch events.\n\n```js\nslideout.enableTouch();\n```\n\n### Slideout.disableTouch();\nDisables opening the slideout via touch events.\n\n```js\nslideout.disableTouch();\n```\n\n### Slideout.on(event, listener);\n```js\nslideout.on('open', function() { ... });\n```\n\n### Slideout.once(event, listener);\n```js\nslideout.once('open', function() { ... });\n```\n\n### Slideout.off(event, listener);\n```js\nslideout.off('open', listener);\n```\n\n### Slideout.emit(event, ...data);\n```js\nslideout.emit('open');\n```\n\n## Events\n\nAn instance of Slideout emits the following events:\n\n- `beforeclose`\n- `close`\n- `beforeopen`\n- `open`\n- `translatestart`\n- `translate`\n- `translateend`\n\nThe slideout emits `translatestart`, `translate` and `translateend` events only when it is opening/closing via touch events.\n\n```js\nslideout.on('translatestart', function() {\n  console.log('Start');\n});\n\nslideout.on('translate', function(translated) {\n  console.log('Translate: ' + translated); // 120 in px\n});\n\nslideout.on('translateend', function() {\n  console.log('End');\n});\n\n// 'Start'\n// 'Translate 120'\n// 'End'\n```\n\n## `data-slideout-ignore` attribute\nYou can use the special HTML attribute `data-slideout-ignore` to disable dragging on some elements. For example, if you have to prevent `slideout` will open when touch on carousels, maps, iframes, etc.\n\n```html\n<main id=\"panel\">\n  <header>\n    <h2>Panel</h2>\n  </header>\n  <div id=\"carousel\" data-slideout-ignore>\n    <h2>Carousel</h2>\n    ...\n  </div>\n</main>\n```\n\n## npm-scripts\n```\n$ npm run build\n```\n\n```\n$ npm run dist\n```\n\n```\n$ npm test\n```\n\n```\n$ npm run hint\n```\n\n## FAQ\n\n### How to add a toggle button.\n\n```js\n// vanilla js\ndocument.querySelector('.toggle-button').addEventListener('click', function() {\n  slideout.toggle();\n});\n\n// jQuery\n$('.toggle-button').on('click', function() {\n    slideout.toggle();\n});\n```\n\n### How to open slideout from right side.\n\nYou should use the `side` option with the value `right`.\n```js\nvar slideout = new Slideout({\n  'panel': document.getElementById('content'),\n  'menu': document.getElementById('menu'),\n  'side': 'right'\n});\n```\n\n### How to enable slideout only on mobile devices.\n\nYou should use `mediaqueries`:\n```css\n@media screen and (min-width: 780px) {\n  .slideout-panel {\n    margin-left: 256px;\n  }\n\n  .slideout-menu {\n    display: block;\n  }\n\n  .btn-hamburger {\n    display: none;\n  }\n}\n```\nDemo: http://codepen.io/pazguille/pen/mEdQvX\n\n### How to use slideout with a fixed header.\n\nFirst, you should define the styles for your fixed header:\n```css\n.fixed-header {\n  position: fixed;\n  width: 100%;\n  height: 50px;\n  backface-visibility: hidden;\n  z-index: 2;\n  background-color: red;\n}\n```\n\nThen, using slideout's events you should translate the fixed header:\n```js\nvar fixed = document.querySelector('.fixed-header');\n\nslideout.on('translate', function(translated) {\n  fixed.style.transform = 'translateX(' + translated + 'px)';\n});\n\nslideout.on('beforeopen', function () {\n  fixed.style.transition = 'transform 300ms ease';\n  fixed.style.transform = 'translateX(256px)';\n});\n\nslideout.on('beforeclose', function () {\n  fixed.style.transition = 'transform 300ms ease';\n  fixed.style.transform = 'translateX(0px)';\n});\n\nslideout.on('open', function () {\n  fixed.style.transition = '';\n});\n\nslideout.on('close', function () {\n  fixed.style.transition = '';\n});\n```\n\nDemo: http://codepen.io/pazguille/pen/ZBxdgw\n\n\n### How to disable dragging on some elements.\nYou can use the attribute `data-slideout-ignore` to disable dragging on some elements:\n\n```html\n<nav id=\"menu\">\n  <header>\n    <h2>Menu</h2>\n  </header>\n</nav>\n\n<main id=\"panel\">\n  <header>\n    <h2>Panel</h2>\n  </header>\n  <div id=\"carousel\" data-slideout-ignore>\n    <h2>Carousel</h2>\n    ...\n  </div>\n</main>\n```\n\n### How to add an overlay to close the menu on click.\nYou can do that using the powerful `slideout` API and a little extra CSS:\n\n```css\n.panel:before {\n  content: '';\n  display: block;\n  background-color: rgba(0,0,0,0);\n  transition: background-color 0.5s ease-in-out;\n}\n\n.panel-open:before {\n  position: absolute;\n  top: 0;\n  bottom: 0;\n  width: 100%;\n  background-color: rgba(0,0,0,.5);\n  z-index: 99;\n}\n```\n\n```js\nfunction close(eve) {\n  eve.preventDefault();\n  slideout.close();\n}\n\nslideout\n  .on('beforeopen', function() {\n    this.panel.classList.add('panel-open');\n  })\n  .on('open', function() {\n    this.panel.addEventListener('click', close);\n  })\n  .on('beforeclose', function() {\n    this.panel.classList.remove('panel-open');\n    this.panel.removeEventListener('click', close);\n  });\n```\n\nDemo: http://codepen.io/pazguille/pen/BQYRYK\n\n## With :heart: by\n- Guille Paz (Front-end developer | Web standards lover)\n- E-mail: [guille87paz@gmail.com](mailto:guille87paz@gmail.com)\n- Twitter: [@pazguille](http://twitter.com/pazguille)\n- Web: [http://pazguille.me](http://pazguille.me)\n\n## License\nMIT license. Copyright © 2015 [Mango](http://getmango.com).\n\n[npm-image]: https://img.shields.io/npm/v/slideout.svg\n[lic-image]: https://img.shields.io/npm/l/slideout.svg\n[npm-link]: https://npmjs.org/package/slideout\n[travis-image]: https://img.shields.io/travis/Mango/slideout.svg\n[travis-link]: https://travis-ci.org/Mango/slideout\n[deps-image]: https://img.shields.io/david/mango/slideout.svg\n[deps-link]: https://david-dm.org/mango/slideout\n[devdeps-image]: https://img.shields.io/david/dev/mango/slideout.svg\n[devdeps-link]: https://david-dm.org/mango/slideout#info=devDependencies\n[dt-image]: https://img.shields.io/npm/dt/slideout.svg\n[coverage-image]: https://img.shields.io/coveralls/Mango/slideout.svg\n[coverage-link]: https://coveralls.io/github/Mango/slideout\n"
  },
  {
    "path": "bower.json",
    "content": "{\n  \"name\": \"slideout.js\",\n  \"repository\": \"https://github.com/Mango/slideout\",\n  \"description\": \"A touch slideout navigation menu for your mobile web apps.\",\n  \"author\": \"Guille Paz <guille87paz@gmail.com>\",\n  \"dependencies\": {\n    \"decouple\": \"0.0.2\",\n    \"emitter-es6\": \"0.0.7\"\n  },\n  \"ignore\": [\n    \".*\",\n    \"package.json\",\n    \"component.json\",\n    \"node_modules\",\n    \"browserify.js\",\n    \"**/.*\",\n    \"bower_components\",\n    \"test\",\n    \"demo\"\n  ],\n  \"homepage\": \"https://github.com/mango/slideout\",\n  \"moduleType\": [\n    \"adecouplemd\",\n    \"globals\",\n    \"node\"\n  ],\n  \"keywords\": [\n    \"slideout\",\n    \"offcanvas\",\n    \"menu\",\n    \"touch\"\n  ],\n  \"main\": \"dist/slideout.js\",\n  \"license\": \"MIT\"\n}\n"
  },
  {
    "path": "browserify.js",
    "content": "'use strict';\n\nvar fs = require('fs');\nvar browserify = require('browserify');\n\nif (!fs.existsSync('./dist')) {\n  fs.mkdirSync('./dist');\n}\n\nbrowserify({'debug': true, 'standalone': 'Slideout'})\n  .require('./index.js', {'entry': true})\n  .bundle()\n  .on('error', function(err) { console.log('Error : ' + err.message); })\n  .pipe(fs.createWriteStream('dist/slideout.js'));"
  },
  {
    "path": "component.json",
    "content": "{\n  \"name\": \"slideout\",\n  \"repo\": \"mango/slideout\",\n  \"description\": \"A touch slideout navigation menu for your mobile web apps.\",\n  \"author\": \"Guille Paz <guille87paz@gmail.com>\",\n  \"version\": \"1.0.1\",\n  \"twitter\": \"@mango\",\n  \"keywords\": [\n    \"slideout\",\n    \"offcanvas\",\n    \"menu\",\n    \"touch\"\n  ],\n  \"dependencies\": {\n    \"pazguille/decouple\": \"0.0.2\",\n    \"Mango/emitter\": \"0.0.7\"\n  },\n  \"development\": {},\n  \"license\": \"MIT\",\n  \"scripts\": [\n    \"index.js\"\n  ]\n}\n"
  },
  {
    "path": "dist/slideout.js",
    "content": "!function(e){if(\"object\"==typeof exports&&\"undefined\"!=typeof module)module.exports=e();else if(\"function\"==typeof define&&define.amd)define([],e);else{var f;\"undefined\"!=typeof window?f=window:\"undefined\"!=typeof global?f=global:\"undefined\"!=typeof self&&(f=self),f.Slideout=e()}}(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require==\"function\"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error(\"Cannot find module '\"+o+\"'\");throw f.code=\"MODULE_NOT_FOUND\",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require==\"function\"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){\n'use strict';\n\n/**\n * Module dependencies\n */\nvar decouple = require('decouple');\nvar Emitter = require('emitter');\n\n/**\n * Privates\n */\nvar scrollTimeout;\nvar scrolling = false;\nvar doc = window.document;\nvar html = doc.documentElement;\nvar msPointerSupported = window.navigator.msPointerEnabled;\nvar touch = {\n  'start': msPointerSupported ? 'MSPointerDown' : 'touchstart',\n  'move': msPointerSupported ? 'MSPointerMove' : 'touchmove',\n  'end': msPointerSupported ? 'MSPointerUp' : 'touchend'\n};\nvar prefix = (function prefix() {\n  var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/;\n  var styleDeclaration = doc.getElementsByTagName('script')[0].style;\n  for (var prop in styleDeclaration) {\n    if (regex.test(prop)) {\n      return '-' + prop.match(regex)[0].toLowerCase() + '-';\n    }\n  }\n  // Nothing found so far? Webkit does not enumerate over the CSS properties of the style object.\n  // However (prop in style) returns the correct value, so we'll have to test for\n  // the precence of a specific property\n  if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; }\n  if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; }\n  return '';\n}());\nfunction extend(destination, from) {\n  for (var prop in from) {\n    if (from[prop]) {\n      destination[prop] = from[prop];\n    }\n  }\n  return destination;\n}\nfunction inherits(child, uber) {\n  child.prototype = extend(child.prototype || {}, uber.prototype);\n}\nfunction hasIgnoredElements(el) {\n  while (el.parentNode) {\n    if (el.getAttribute('data-slideout-ignore') !== null) {\n      return el;\n    }\n    el = el.parentNode;\n  }\n  return null;\n}\n\n/**\n * Slideout constructor\n */\nfunction Slideout(options) {\n  options = options || {};\n\n  // Sets default values\n  this._startOffsetX = 0;\n  this._currentOffsetX = 0;\n  this._opening = false;\n  this._moved = false;\n  this._opened = false;\n  this._preventOpen = false;\n\n  // Sets panel\n  this.panel = options.panel;\n  this.menu = options.menu;\n\n  // Sets options\n  this._touch = options.touch === undefined ? true : options.touch && true;\n  this._side = options.side || 'left';\n  this._easing = options.fx || options.easing || 'ease';\n  this._duration = parseInt(options.duration, 10) || 300;\n  this._tolerance = parseInt(options.tolerance, 10) || 70;\n  this._padding = this._translateTo = parseInt(options.padding, 10) || 256;\n  this._orientation = this._side === 'right' ? -1 : 1;\n  this._translateTo *= this._orientation;\n\n  // Sets  classnames\n  if (!this.panel.classList.contains('slideout-panel')) {\n    this.panel.classList.add('slideout-panel');\n  }\n  if (!this.panel.classList.contains('slideout-panel-' + this._side)) {\n    this.panel.classList.add('slideout-panel-' + this._side);\n  }\n  if (!this.menu.classList.contains('slideout-menu')) {\n    this.menu.classList.add('slideout-menu');\n  }\n  if (!this.menu.classList.contains('slideout-menu-' + this._side)) {\n    this.menu.classList.add('slideout-menu-' + this._side);\n  }\n\n  // Init touch events\n  if (this._touch) {\n    this._initTouchEvents();\n  }\n}\n\n/**\n * Inherits from Emitter\n */\ninherits(Slideout, Emitter);\n\n/**\n * Opens the slideout menu.\n */\nSlideout.prototype.open = function() {\n  var self = this;\n  this.emit('beforeopen');\n  if (!html.classList.contains('slideout-open')) {\n    html.classList.add('slideout-open');\n  }\n  this._setTransition();\n  this._translateXTo(this._translateTo);\n  this._opened = true;\n  setTimeout(function() {\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = '';\n    self.emit('open');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Closes slideout menu.\n */\nSlideout.prototype.close = function() {\n  var self = this;\n  if (!this.isOpen() && !this._opening) {\n    return this;\n  }\n  this.emit('beforeclose');\n  this._setTransition();\n  this._translateXTo(0);\n  this._opened = false;\n  setTimeout(function() {\n    html.classList.remove('slideout-open');\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = '';\n    self.emit('close');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Toggles (open/close) slideout menu.\n */\nSlideout.prototype.toggle = function() {\n  return this.isOpen() ? this.close() : this.open();\n};\n\n/**\n * Returns true if the slideout is currently open, and false if it is closed.\n */\nSlideout.prototype.isOpen = function() {\n  return this._opened;\n};\n\n/**\n * Translates panel and updates currentOffset with a given X point\n */\nSlideout.prototype._translateXTo = function(translateX) {\n  this._currentOffsetX = translateX;\n  this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translateX(' + translateX + 'px)';\n  return this;\n};\n\n/**\n * Set transition properties\n */\nSlideout.prototype._setTransition = function() {\n  this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._easing;\n  return this;\n};\n\n/**\n * Initializes touch event\n */\nSlideout.prototype._initTouchEvents = function() {\n  var self = this;\n\n  /**\n   * Decouple scroll event\n   */\n  this._onScrollFn = decouple(doc, 'scroll', function() {\n    if (!self._moved) {\n      clearTimeout(scrollTimeout);\n      scrolling = true;\n      scrollTimeout = setTimeout(function() {\n        scrolling = false;\n      }, 250);\n    }\n  });\n\n  /**\n   * Prevents touchmove event if slideout is moving\n   */\n  this._preventMove = function(eve) {\n    if (self._moved) {\n      eve.preventDefault();\n    }\n  };\n\n  doc.addEventListener(touch.move, this._preventMove);\n\n  /**\n   * Resets values on touchstart\n   */\n  this._resetTouchFn = function(eve) {\n    if (typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    self._moved = false;\n    self._opening = false;\n    self._startOffsetX = eve.touches[0].pageX;\n    self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0));\n  };\n\n  this.panel.addEventListener(touch.start, this._resetTouchFn);\n\n  /**\n   * Resets values on touchcancel\n   */\n  this._onTouchCancelFn = function() {\n    self._moved = false;\n    self._opening = false;\n  };\n\n  this.panel.addEventListener('touchcancel', this._onTouchCancelFn);\n\n  /**\n   * Toggles slideout on touchend\n   */\n  this._onTouchEndFn = function() {\n    if (self._moved) {\n      self.emit('translateend');\n      (self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close();\n    }\n    self._moved = false;\n  };\n\n  this.panel.addEventListener(touch.end, this._onTouchEndFn);\n\n  /**\n   * Translates panel on touchmove\n   */\n  this._onTouchMoveFn = function(eve) {\n    if (\n      scrolling ||\n      self._preventOpen ||\n      typeof eve.touches === 'undefined' ||\n      hasIgnoredElements(eve.target)\n    ) {\n      return;\n    }\n\n    var dif_x = eve.touches[0].clientX - self._startOffsetX;\n    var translateX = self._currentOffsetX = dif_x;\n\n    if (Math.abs(translateX) > self._padding) {\n      return;\n    }\n\n    if (Math.abs(dif_x) > 20) {\n\n      self._opening = true;\n\n      var oriented_dif_x = dif_x * self._orientation;\n\n      if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) {\n        return;\n      }\n\n      if (!self._moved) {\n        self.emit('translatestart');\n      }\n\n      if (oriented_dif_x <= 0) {\n        translateX = dif_x + self._padding * self._orientation;\n        self._opening = false;\n      }\n\n      if (!(self._moved && html.classList.contains('slideout-open'))) {\n        html.classList.add('slideout-open');\n      }\n\n      self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translateX(' + translateX + 'px)';\n      self.emit('translate', translateX);\n      self._moved = true;\n    }\n\n  };\n\n  this.panel.addEventListener(touch.move, this._onTouchMoveFn);\n\n  return this;\n};\n\n/**\n * Enable opening the slideout via touch events.\n */\nSlideout.prototype.enableTouch = function() {\n  this._touch = true;\n  return this;\n};\n\n/**\n * Disable opening the slideout via touch events.\n */\nSlideout.prototype.disableTouch = function() {\n  this._touch = false;\n  return this;\n};\n\n/**\n * Destroy an instance of slideout.\n */\nSlideout.prototype.destroy = function() {\n  // Close before clean\n  this.close();\n\n  // Remove event listeners\n  doc.removeEventListener(touch.move, this._preventMove);\n  this.panel.removeEventListener(touch.start, this._resetTouchFn);\n  this.panel.removeEventListener('touchcancel', this._onTouchCancelFn);\n  this.panel.removeEventListener(touch.end, this._onTouchEndFn);\n  this.panel.removeEventListener(touch.move, this._onTouchMoveFn);\n  doc.removeEventListener('scroll', this._onScrollFn);\n\n  // Remove methods\n  this.open = this.close = function() {};\n\n  // Return the instance so it can be easily dereferenced\n  return this;\n};\n\n/**\n * Expose Slideout\n */\nmodule.exports = Slideout;\n\n},{\"decouple\":2,\"emitter\":3}],2:[function(require,module,exports){\n'use strict';\n\nvar requestAnimFrame = (function() {\n  return window.requestAnimationFrame ||\n    window.webkitRequestAnimationFrame ||\n    function (callback) {\n      window.setTimeout(callback, 1000 / 60);\n    };\n}());\n\nfunction decouple(node, event, fn) {\n  var eve,\n      tracking = false;\n\n  function captureEvent(e) {\n    eve = e;\n    track();\n  }\n\n  function track() {\n    if (!tracking) {\n      requestAnimFrame(update);\n      tracking = true;\n    }\n  }\n\n  function update() {\n    fn.call(node, eve);\n    tracking = false;\n  }\n\n  node.addEventListener(event, captureEvent, false);\n\n  return captureEvent;\n}\n\n/**\n * Expose decouple\n */\nmodule.exports = decouple;\n\n},{}],3:[function(require,module,exports){\n\"use strict\";\n\nvar _classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } };\n\nexports.__esModule = true;\n/**\n * Creates a new instance of Emitter.\n * @class\n * @returns {Object} Returns a new instance of Emitter.\n * @example\n * // Creates a new instance of Emitter.\n * var Emitter = require('emitter');\n *\n * var emitter = new Emitter();\n */\n\nvar Emitter = (function () {\n  function Emitter() {\n    _classCallCheck(this, Emitter);\n  }\n\n  /**\n   * Adds a listener to the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Add an event listener to \"foo\" event.\n   * emitter.on('foo', listener);\n   */\n\n  Emitter.prototype.on = function on(event, listener) {\n    // Use the current collection or create it.\n    this._eventCollection = this._eventCollection || {};\n\n    // Use the current collection of an event or create it.\n    this._eventCollection[event] = this._eventCollection[event] || [];\n\n    // Appends the listener into the collection of the given event\n    this._eventCollection[event].push(listener);\n\n    return this;\n  };\n\n  /**\n   * Adds a listener to the collection for the specified event that will be called only once.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to add.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Will add an event handler to \"foo\" event once.\n   * emitter.once('foo', listener);\n   */\n\n  Emitter.prototype.once = function once(event, listener) {\n    var self = this;\n\n    function fn() {\n      self.off(event, fn);\n      listener.apply(this, arguments);\n    }\n\n    fn.listener = listener;\n\n    this.on(event, fn);\n\n    return this;\n  };\n\n  /**\n   * Removes a listener from the collection for the specified event.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The event name.\n   * @param {Function} listener - A listener function to remove.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Remove a given listener.\n   * emitter.off('foo', listener);\n   */\n\n  Emitter.prototype.off = function off(event, listener) {\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    listeners.forEach(function (fn, i) {\n      if (fn === listener || fn.listener === listener) {\n        // Removes the given listener.\n        listeners.splice(i, 1);\n      }\n    });\n\n    // Removes an empty event collection.\n    if (listeners.length === 0) {\n      delete this._eventCollection[event];\n    }\n\n    return this;\n  };\n\n  /**\n   * Execute each item in the listener collection in order with the specified data.\n   * @memberof! Emitter.prototype\n   * @function\n   * @param {String} event - The name of the event you want to emit.\n   * @param {...Object} data - Data to pass to the listeners.\n   * @returns {Object} Returns an instance of Emitter.\n   * @example\n   * // Emits the \"foo\" event with 'param1' and 'param2' as arguments.\n   * emitter.emit('foo', 'param1', 'param2');\n   */\n\n  Emitter.prototype.emit = function emit(event) {\n    var _this = this;\n\n    for (var _len = arguments.length, args = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {\n      args[_key - 1] = arguments[_key];\n    }\n\n    var listeners = undefined;\n\n    // Defines listeners value.\n    if (!this._eventCollection || !(listeners = this._eventCollection[event])) {\n      return this;\n    }\n\n    // Clone listeners\n    listeners = listeners.slice(0);\n\n    listeners.forEach(function (fn) {\n      return fn.apply(_this, args);\n    });\n\n    return this;\n  };\n\n  return Emitter;\n})();\n\n/**\n * Exports Emitter\n */\nexports[\"default\"] = Emitter;\nmodule.exports = exports[\"default\"];\n},{}]},{},[1])(1)\n});\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJpbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9kZWNvdXBsZS9pbmRleC5qcyIsIm5vZGVfbW9kdWxlcy9lbWl0dGVyL2Rpc3QvaW5kZXguanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7QUNBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQzFWQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3hDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0EiLCJmaWxlIjoiZ2VuZXJhdGVkLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXNDb250ZW50IjpbIihmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc30pIiwiJ3VzZSBzdHJpY3QnO1xuXG4vKipcbiAqIE1vZHVsZSBkZXBlbmRlbmNpZXNcbiAqL1xudmFyIGRlY291cGxlID0gcmVxdWlyZSgnZGVjb3VwbGUnKTtcbnZhciBFbWl0dGVyID0gcmVxdWlyZSgnZW1pdHRlcicpO1xuXG4vKipcbiAqIFByaXZhdGVzXG4gKi9cbnZhciBzY3JvbGxUaW1lb3V0O1xudmFyIHNjcm9sbGluZyA9IGZhbHNlO1xudmFyIGRvYyA9IHdpbmRvdy5kb2N1bWVudDtcbnZhciBodG1sID0gZG9jLmRvY3VtZW50RWxlbWVudDtcbnZhciBtc1BvaW50ZXJTdXBwb3J0ZWQgPSB3aW5kb3cubmF2aWdhdG9yLm1zUG9pbnRlckVuYWJsZWQ7XG52YXIgdG91Y2ggPSB7XG4gICdzdGFydCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJEb3duJyA6ICd0b3VjaHN0YXJ0JyxcbiAgJ21vdmUnOiBtc1BvaW50ZXJTdXBwb3J0ZWQgPyAnTVNQb2ludGVyTW92ZScgOiAndG91Y2htb3ZlJyxcbiAgJ2VuZCc6IG1zUG9pbnRlclN1cHBvcnRlZCA/ICdNU1BvaW50ZXJVcCcgOiAndG91Y2hlbmQnXG59O1xudmFyIHByZWZpeCA9IChmdW5jdGlvbiBwcmVmaXgoKSB7XG4gIHZhciByZWdleCA9IC9eKFdlYmtpdHxLaHRtbHxNb3p8bXN8TykoPz1bQS1aXSkvO1xuICB2YXIgc3R5bGVEZWNsYXJhdGlvbiA9IGRvYy5nZXRFbGVtZW50c0J5VGFnTmFtZSgnc2NyaXB0JylbMF0uc3R5bGU7XG4gIGZvciAodmFyIHByb3AgaW4gc3R5bGVEZWNsYXJhdGlvbikge1xuICAgIGlmIChyZWdleC50ZXN0KHByb3ApKSB7XG4gICAgICByZXR1cm4gJy0nICsgcHJvcC5tYXRjaChyZWdleClbMF0udG9Mb3dlckNhc2UoKSArICctJztcbiAgICB9XG4gIH1cbiAgLy8gTm90aGluZyBmb3VuZCBzbyBmYXI/IFdlYmtpdCBkb2VzIG5vdCBlbnVtZXJhdGUgb3ZlciB0aGUgQ1NTIHByb3BlcnRpZXMgb2YgdGhlIHN0eWxlIG9iamVjdC5cbiAgLy8gSG93ZXZlciAocHJvcCBpbiBzdHlsZSkgcmV0dXJucyB0aGUgY29ycmVjdCB2YWx1ZSwgc28gd2UnbGwgaGF2ZSB0byB0ZXN0IGZvclxuICAvLyB0aGUgcHJlY2VuY2Ugb2YgYSBzcGVjaWZpYyBwcm9wZXJ0eVxuICBpZiAoJ1dlYmtpdE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICctd2Via2l0LSc7IH1cbiAgaWYgKCdLaHRtbE9wYWNpdHknIGluIHN0eWxlRGVjbGFyYXRpb24pIHsgcmV0dXJuICcta2h0bWwtJzsgfVxuICByZXR1cm4gJyc7XG59KCkpO1xuZnVuY3Rpb24gZXh0ZW5kKGRlc3RpbmF0aW9uLCBmcm9tKSB7XG4gIGZvciAodmFyIHByb3AgaW4gZnJvbSkge1xuICAgIGlmIChmcm9tW3Byb3BdKSB7XG4gICAgICBkZXN0aW5hdGlvbltwcm9wXSA9IGZyb21bcHJvcF07XG4gICAgfVxuICB9XG4gIHJldHVybiBkZXN0aW5hdGlvbjtcbn1cbmZ1bmN0aW9uIGluaGVyaXRzKGNoaWxkLCB1YmVyKSB7XG4gIGNoaWxkLnByb3RvdHlwZSA9IGV4dGVuZChjaGlsZC5wcm90b3R5cGUgfHwge30sIHViZXIucHJvdG90eXBlKTtcbn1cbmZ1bmN0aW9uIGhhc0lnbm9yZWRFbGVtZW50cyhlbCkge1xuICB3aGlsZSAoZWwucGFyZW50Tm9kZSkge1xuICAgIGlmIChlbC5nZXRBdHRyaWJ1dGUoJ2RhdGEtc2xpZGVvdXQtaWdub3JlJykgIT09IG51bGwpIHtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgZWwgPSBlbC5wYXJlbnROb2RlO1xuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG4vKipcbiAqIFNsaWRlb3V0IGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFNsaWRlb3V0KG9wdGlvbnMpIHtcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgLy8gU2V0cyBkZWZhdWx0IHZhbHVlc1xuICB0aGlzLl9zdGFydE9mZnNldFggPSAwO1xuICB0aGlzLl9jdXJyZW50T2Zmc2V0WCA9IDA7XG4gIHRoaXMuX29wZW5pbmcgPSBmYWxzZTtcbiAgdGhpcy5fbW92ZWQgPSBmYWxzZTtcbiAgdGhpcy5fb3BlbmVkID0gZmFsc2U7XG4gIHRoaXMuX3ByZXZlbnRPcGVuID0gZmFsc2U7XG5cbiAgLy8gU2V0cyBwYW5lbFxuICB0aGlzLnBhbmVsID0gb3B0aW9ucy5wYW5lbDtcbiAgdGhpcy5tZW51ID0gb3B0aW9ucy5tZW51O1xuXG4gIC8vIFNldHMgb3B0aW9uc1xuICB0aGlzLl90b3VjaCA9IG9wdGlvbnMudG91Y2ggPT09IHVuZGVmaW5lZCA/IHRydWUgOiBvcHRpb25zLnRvdWNoICYmIHRydWU7XG4gIHRoaXMuX3NpZGUgPSBvcHRpb25zLnNpZGUgfHwgJ2xlZnQnO1xuICB0aGlzLl9lYXNpbmcgPSBvcHRpb25zLmZ4IHx8wqBvcHRpb25zLmVhc2luZyB8fCAnZWFzZSc7XG4gIHRoaXMuX2R1cmF0aW9uID0gcGFyc2VJbnQob3B0aW9ucy5kdXJhdGlvbiwgMTApIHx8IDMwMDtcbiAgdGhpcy5fdG9sZXJhbmNlID0gcGFyc2VJbnQob3B0aW9ucy50b2xlcmFuY2UsIDEwKSB8fCA3MDtcbiAgdGhpcy5fcGFkZGluZyA9IHRoaXMuX3RyYW5zbGF0ZVRvID0gcGFyc2VJbnQob3B0aW9ucy5wYWRkaW5nLCAxMCkgfHwgMjU2O1xuICB0aGlzLl9vcmllbnRhdGlvbiA9IHRoaXMuX3NpZGUgPT09ICdyaWdodCcgPyAtMSA6IDE7XG4gIHRoaXMuX3RyYW5zbGF0ZVRvICo9IHRoaXMuX29yaWVudGF0aW9uO1xuXG4gIC8vIFNldHMgIGNsYXNzbmFtZXNcbiAgaWYgKCF0aGlzLnBhbmVsLmNsYXNzTGlzdC5jb250YWlucygnc2xpZGVvdXQtcGFuZWwnKSkge1xuICAgIHRoaXMucGFuZWwuY2xhc3NMaXN0LmFkZCgnc2xpZGVvdXQtcGFuZWwnKTtcbiAgfVxuICBpZiAoIXRoaXMucGFuZWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdzbGlkZW91dC1wYW5lbC0nICsgdGhpcy5fc2lkZSkpIHtcbiAgICB0aGlzLnBhbmVsLmNsYXNzTGlzdC5hZGQoJ3NsaWRlb3V0LXBhbmVsLScgKyB0aGlzLl9zaWRlKTtcbiAgfVxuICBpZiAoIXRoaXMubWVudS5jbGFzc0xpc3QuY29udGFpbnMoJ3NsaWRlb3V0LW1lbnUnKSkge1xuICAgIHRoaXMubWVudS5jbGFzc0xpc3QuYWRkKCdzbGlkZW91dC1tZW51Jyk7XG4gIH1cbiAgaWYgKCF0aGlzLm1lbnUuY2xhc3NMaXN0LmNvbnRhaW5zKCdzbGlkZW91dC1tZW51LScgKyB0aGlzLl9zaWRlKSkge1xuICAgIHRoaXMubWVudS5jbGFzc0xpc3QuYWRkKCdzbGlkZW91dC1tZW51LScgKyB0aGlzLl9zaWRlKTtcbiAgfVxuXG4gIC8vIEluaXQgdG91Y2ggZXZlbnRzXG4gIGlmICh0aGlzLl90b3VjaCkge1xuICAgIHRoaXMuX2luaXRUb3VjaEV2ZW50cygpO1xuICB9XG59XG5cbi8qKlxuICogSW5oZXJpdHMgZnJvbSBFbWl0dGVyXG4gKi9cbmluaGVyaXRzKFNsaWRlb3V0LCBFbWl0dGVyKTtcblxuLyoqXG4gKiBPcGVucyB0aGUgc2xpZGVvdXQgbWVudS5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLm9wZW4gPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlbGYgPSB0aGlzO1xuICB0aGlzLmVtaXQoJ2JlZm9yZW9wZW4nKTtcbiAgaWYgKCFodG1sLmNsYXNzTGlzdC5jb250YWlucygnc2xpZGVvdXQtb3BlbicpKSB7XG4gICAgaHRtbC5jbGFzc0xpc3QuYWRkKCdzbGlkZW91dC1vcGVuJyk7XG4gIH1cbiAgdGhpcy5fc2V0VHJhbnNpdGlvbigpO1xuICB0aGlzLl90cmFuc2xhdGVYVG8odGhpcy5fdHJhbnNsYXRlVG8pO1xuICB0aGlzLl9vcGVuZWQgPSB0cnVlO1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIHNlbGYucGFuZWwuc3R5bGUudHJhbnNpdGlvbiA9IHNlbGYucGFuZWwuc3R5bGVbJy13ZWJraXQtdHJhbnNpdGlvbiddID0gJyc7XG4gICAgc2VsZi5lbWl0KCdvcGVuJyk7XG4gIH0sIHRoaXMuX2R1cmF0aW9uICsgNTApO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2xvc2VzIHNsaWRlb3V0IG1lbnUuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5jbG9zZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgc2VsZiA9IHRoaXM7XG4gIGlmICghdGhpcy5pc09wZW4oKSAmJiAhdGhpcy5fb3BlbmluZykge1xuICAgIHJldHVybiB0aGlzO1xuICB9XG4gIHRoaXMuZW1pdCgnYmVmb3JlY2xvc2UnKTtcbiAgdGhpcy5fc2V0VHJhbnNpdGlvbigpO1xuICB0aGlzLl90cmFuc2xhdGVYVG8oMCk7XG4gIHRoaXMuX29wZW5lZCA9IGZhbHNlO1xuICBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgIGh0bWwuY2xhc3NMaXN0LnJlbW92ZSgnc2xpZGVvdXQtb3BlbicpO1xuICAgIHNlbGYucGFuZWwuc3R5bGUudHJhbnNpdGlvbiA9IHNlbGYucGFuZWwuc3R5bGVbJy13ZWJraXQtdHJhbnNpdGlvbiddID0gc2VsZi5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNmb3JtJ10gPSBzZWxmLnBhbmVsLnN0eWxlLnRyYW5zZm9ybSA9ICcnO1xuICAgIHNlbGYuZW1pdCgnY2xvc2UnKTtcbiAgfSwgdGhpcy5fZHVyYXRpb24gKyA1MCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBUb2dnbGVzIChvcGVuL2Nsb3NlKSBzbGlkZW91dCBtZW51LlxuICovXG5TbGlkZW91dC5wcm90b3R5cGUudG9nZ2xlID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmlzT3BlbigpID8gdGhpcy5jbG9zZSgpIDogdGhpcy5vcGVuKCk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdHJ1ZSBpZiB0aGUgc2xpZGVvdXQgaXMgY3VycmVudGx5IG9wZW4sIGFuZCBmYWxzZSBpZiBpdCBpcyBjbG9zZWQuXG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5pc09wZW4gPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX29wZW5lZDtcbn07XG5cbi8qKlxuICogVHJhbnNsYXRlcyBwYW5lbCBhbmQgdXBkYXRlcyBjdXJyZW50T2Zmc2V0IHdpdGggYSBnaXZlbiBYIHBvaW50XG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5fdHJhbnNsYXRlWFRvID0gZnVuY3Rpb24odHJhbnNsYXRlWCkge1xuICB0aGlzLl9jdXJyZW50T2Zmc2V0WCA9IHRyYW5zbGF0ZVg7XG4gIHRoaXMucGFuZWwuc3R5bGVbcHJlZml4ICsgJ3RyYW5zZm9ybSddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2Zvcm0gPSAndHJhbnNsYXRlWCgnICsgdHJhbnNsYXRlWCArICdweCknO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogU2V0IHRyYW5zaXRpb24gcHJvcGVydGllc1xuICovXG5TbGlkZW91dC5wcm90b3R5cGUuX3NldFRyYW5zaXRpb24gPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5wYW5lbC5zdHlsZVtwcmVmaXggKyAndHJhbnNpdGlvbiddID0gdGhpcy5wYW5lbC5zdHlsZS50cmFuc2l0aW9uID0gcHJlZml4ICsgJ3RyYW5zZm9ybSAnICsgdGhpcy5fZHVyYXRpb24gKyAnbXMgJyArIHRoaXMuX2Vhc2luZztcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIEluaXRpYWxpemVzIHRvdWNoIGV2ZW50XG4gKi9cblNsaWRlb3V0LnByb3RvdHlwZS5faW5pdFRvdWNoRXZlbnRzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZWxmID0gdGhpcztcblxuICAvKipcbiAgICogRGVjb3VwbGUgc2Nyb2xsIGV2ZW50XG4gICAqL1xuICB0aGlzLl9vblNjcm9sbEZuID0gZGVjb3VwbGUoZG9jLCAnc2Nyb2xsJywgZnVuY3Rpb24oKSB7XG4gICAgaWYgKCFzZWxmLl9tb3ZlZCkge1xuICAgICAgY2xlYXJUaW1lb3V0KHNjcm9sbFRpbWVvdXQpO1xuICAgICAgc2Nyb2xsaW5nID0gdHJ1ZTtcbiAgICAgIHNjcm9sbFRpbWVvdXQgPSBzZXRUaW1lb3V0KGZ1bmN0aW9uKCkge1xuICAgICAgICBzY3JvbGxpbmcgPSBmYWxzZTtcbiAgICAgIH0sIDI1MCk7XG4gICAgfVxuICB9KTtcblxuICAvKipcbiAgICogUHJldmVudHMgdG91Y2htb3ZlIGV2ZW50IGlmIHNsaWRlb3V0IGlzIG1vdmluZ1xuICAgKi9cbiAgdGhpcy5fcHJldmVudE1vdmUgPSBmdW5jdGlvbihldmUpIHtcbiAgICBpZiAoc2VsZi5fbW92ZWQpIHtcbiAgICAgIGV2ZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIH1cbiAgfTtcblxuICBkb2MuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaC5tb3ZlLCB0aGlzLl9wcmV2ZW50TW92ZSk7XG5cbiAgLyoqXG4gICAqIFJlc2V0cyB2YWx1ZXMgb24gdG91Y2hzdGFydFxuICAgKi9cbiAgdGhpcy5fcmVzZXRUb3VjaEZuID0gZnVuY3Rpb24oZXZlKSB7XG4gICAgaWYgKHR5cGVvZiBldmUudG91Y2hlcyA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZWxmLl9tb3ZlZCA9IGZhbHNlO1xuICAgIHNlbGYuX29wZW5pbmcgPSBmYWxzZTtcbiAgICBzZWxmLl9zdGFydE9mZnNldFggPSBldmUudG91Y2hlc1swXS5wYWdlWDtcbiAgICBzZWxmLl9wcmV2ZW50T3BlbiA9ICghc2VsZi5fdG91Y2ggfHwgKCFzZWxmLmlzT3BlbigpICYmIHNlbGYubWVudS5jbGllbnRXaWR0aCAhPT0gMCkpO1xuICB9O1xuXG4gIHRoaXMucGFuZWwuYWRkRXZlbnRMaXN0ZW5lcih0b3VjaC5zdGFydCwgdGhpcy5fcmVzZXRUb3VjaEZuKTtcblxuICAvKipcbiAgICogUmVzZXRzIHZhbHVlcyBvbiB0b3VjaGNhbmNlbFxuICAgKi9cbiAgdGhpcy5fb25Ub3VjaENhbmNlbEZuID0gZnVuY3Rpb24oKSB7XG4gICAgc2VsZi5fbW92ZWQgPSBmYWxzZTtcbiAgICBzZWxmLl9vcGVuaW5nID0gZmFsc2U7XG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaGNhbmNlbCcsIHRoaXMuX29uVG91Y2hDYW5jZWxGbik7XG5cbiAgLyoqXG4gICAqIFRvZ2dsZXMgc2xpZGVvdXQgb24gdG91Y2hlbmRcbiAgICovXG4gIHRoaXMuX29uVG91Y2hFbmRGbiA9IGZ1bmN0aW9uKCkge1xuICAgIGlmIChzZWxmLl9tb3ZlZCkge1xuICAgICAgc2VsZi5lbWl0KCd0cmFuc2xhdGVlbmQnKTtcbiAgICAgIChzZWxmLl9vcGVuaW5nICYmIE1hdGguYWJzKHNlbGYuX2N1cnJlbnRPZmZzZXRYKSA+IHNlbGYuX3RvbGVyYW5jZSkgPyBzZWxmLm9wZW4oKSA6IHNlbGYuY2xvc2UoKTtcbiAgICB9XG4gICAgc2VsZi5fbW92ZWQgPSBmYWxzZTtcbiAgfTtcblxuICB0aGlzLnBhbmVsLmFkZEV2ZW50TGlzdGVuZXIodG91Y2guZW5kLCB0aGlzLl9vblRvdWNoRW5kRm4pO1xuXG4gIC8qKlxuICAgKiBUcmFuc2xhdGVzIHBhbmVsIG9uIHRvdWNobW92ZVxuICAgKi9cbiAgdGhpcy5fb25Ub3VjaE1vdmVGbiA9IGZ1bmN0aW9uKGV2ZSkge1xuICAgIGlmIChcbiAgICAgIHNjcm9sbGluZyB8fFxuICAgICAgc2VsZi5fcHJldmVudE9wZW4gfHxcbiAgICAgIHR5cGVvZiBldmUudG91Y2hlcyA9PT0gJ3VuZGVmaW5lZCcgfHxcbiAgICAgIGhhc0lnbm9yZWRFbGVtZW50cyhldmUudGFyZ2V0KVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciBkaWZfeCA9IGV2ZS50b3VjaGVzWzBdLmNsaWVudFggLSBzZWxmLl9zdGFydE9mZnNldFg7XG4gICAgdmFyIHRyYW5zbGF0ZVggPSBzZWxmLl9jdXJyZW50T2Zmc2V0WCA9IGRpZl94O1xuXG4gICAgaWYgKE1hdGguYWJzKHRyYW5zbGF0ZVgpID4gc2VsZi5fcGFkZGluZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmIChNYXRoLmFicyhkaWZfeCkgPiAyMCkge1xuXG4gICAgICBzZWxmLl9vcGVuaW5nID0gdHJ1ZTtcblxuICAgICAgdmFyIG9yaWVudGVkX2RpZl94ID0gZGlmX3ggKiBzZWxmLl9vcmllbnRhdGlvbjtcblxuICAgICAgaWYgKHNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA+IDAgfHwgIXNlbGYuX29wZW5lZCAmJiBvcmllbnRlZF9kaWZfeCA8IDApIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAoIXNlbGYuX21vdmVkKSB7XG4gICAgICAgIHNlbGYuZW1pdCgndHJhbnNsYXRlc3RhcnQnKTtcbiAgICAgIH1cblxuICAgICAgaWYgKG9yaWVudGVkX2RpZl94IDw9IDApIHtcbiAgICAgICAgdHJhbnNsYXRlWCA9IGRpZl94ICsgc2VsZi5fcGFkZGluZyAqIHNlbGYuX29yaWVudGF0aW9uO1xuICAgICAgICBzZWxmLl9vcGVuaW5nID0gZmFsc2U7XG4gICAgICB9XG5cbiAgICAgIGlmICghKHNlbGYuX21vdmVkICYmIGh0bWwuY2xhc3NMaXN0LmNvbnRhaW5zKCdzbGlkZW91dC1vcGVuJykpKSB7XG4gICAgICAgIGh0bWwuY2xhc3NMaXN0LmFkZCgnc2xpZGVvdXQtb3BlbicpO1xuICAgICAgfVxuXG4gICAgICBzZWxmLnBhbmVsLnN0eWxlW3ByZWZpeCArICd0cmFuc2Zvcm0nXSA9IHNlbGYucGFuZWwuc3R5bGUudHJhbnNmb3JtID0gJ3RyYW5zbGF0ZVgoJyArIHRyYW5zbGF0ZVggKyAncHgpJztcbiAgICAgIHNlbGYuZW1pdCgndHJhbnNsYXRlJywgdHJhbnNsYXRlWCk7XG4gICAgICBzZWxmLl9tb3ZlZCA9IHRydWU7XG4gICAgfVxuXG4gIH07XG5cbiAgdGhpcy5wYW5lbC5hZGRFdmVudExpc3RlbmVyKHRvdWNoLm1vdmUsIHRoaXMuX29uVG91Y2hNb3ZlRm4pO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBFbmFibGUgb3BlbmluZyB0aGUgc2xpZGVvdXQgdmlhIHRvdWNoIGV2ZW50cy5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLmVuYWJsZVRvdWNoID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMuX3RvdWNoID0gdHJ1ZTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIERpc2FibGUgb3BlbmluZyB0aGUgc2xpZGVvdXQgdmlhIHRvdWNoIGV2ZW50cy5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLmRpc2FibGVUb3VjaCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl90b3VjaCA9IGZhbHNlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRGVzdHJveSBhbiBpbnN0YW5jZSBvZiBzbGlkZW91dC5cbiAqL1xuU2xpZGVvdXQucHJvdG90eXBlLmRlc3Ryb3kgPSBmdW5jdGlvbigpIHtcbiAgLy8gQ2xvc2UgYmVmb3JlIGNsZWFuXG4gIHRoaXMuY2xvc2UoKTtcblxuICAvLyBSZW1vdmUgZXZlbnQgbGlzdGVuZXJzXG4gIGRvYy5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoLm1vdmUsIHRoaXMuX3ByZXZlbnRNb3ZlKTtcbiAgdGhpcy5wYW5lbC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoLnN0YXJ0LCB0aGlzLl9yZXNldFRvdWNoRm4pO1xuICB0aGlzLnBhbmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3RvdWNoY2FuY2VsJywgdGhpcy5fb25Ub3VjaENhbmNlbEZuKTtcbiAgdGhpcy5wYW5lbC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoLmVuZCwgdGhpcy5fb25Ub3VjaEVuZEZuKTtcbiAgdGhpcy5wYW5lbC5yZW1vdmVFdmVudExpc3RlbmVyKHRvdWNoLm1vdmUsIHRoaXMuX29uVG91Y2hNb3ZlRm4pO1xuICBkb2MucmVtb3ZlRXZlbnRMaXN0ZW5lcignc2Nyb2xsJywgdGhpcy5fb25TY3JvbGxGbik7XG5cbiAgLy8gUmVtb3ZlIG1ldGhvZHNcbiAgdGhpcy5vcGVuID0gdGhpcy5jbG9zZSA9IGZ1bmN0aW9uKCkge307XG5cbiAgLy8gUmV0dXJuIHRoZSBpbnN0YW5jZSBzbyBpdCBjYW4gYmUgZWFzaWx5IGRlcmVmZXJlbmNlZFxuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogRXhwb3NlIFNsaWRlb3V0XG4gKi9cbm1vZHVsZS5leHBvcnRzID0gU2xpZGVvdXQ7XG4iLCIndXNlIHN0cmljdCc7XG5cbnZhciByZXF1ZXN0QW5pbUZyYW1lID0gKGZ1bmN0aW9uKCkge1xuICByZXR1cm4gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSB8fFxuICAgIHdpbmRvdy53ZWJraXRSZXF1ZXN0QW5pbWF0aW9uRnJhbWUgfHxcbiAgICBmdW5jdGlvbiAoY2FsbGJhY2spIHtcbiAgICAgIHdpbmRvdy5zZXRUaW1lb3V0KGNhbGxiYWNrLCAxMDAwIC8gNjApO1xuICAgIH07XG59KCkpO1xuXG5mdW5jdGlvbiBkZWNvdXBsZShub2RlLCBldmVudCwgZm4pIHtcbiAgdmFyIGV2ZSxcbiAgICAgIHRyYWNraW5nID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gY2FwdHVyZUV2ZW50KGUpIHtcbiAgICBldmUgPSBlO1xuICAgIHRyYWNrKCk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFjaygpIHtcbiAgICBpZiAoIXRyYWNraW5nKSB7XG4gICAgICByZXF1ZXN0QW5pbUZyYW1lKHVwZGF0ZSk7XG4gICAgICB0cmFja2luZyA9IHRydWU7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gdXBkYXRlKCkge1xuICAgIGZuLmNhbGwobm9kZSwgZXZlKTtcbiAgICB0cmFja2luZyA9IGZhbHNlO1xuICB9XG5cbiAgbm9kZS5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBjYXB0dXJlRXZlbnQsIGZhbHNlKTtcblxuICByZXR1cm4gY2FwdHVyZUV2ZW50O1xufVxuXG4vKipcbiAqIEV4cG9zZSBkZWNvdXBsZVxuICovXG5tb2R1bGUuZXhwb3J0cyA9IGRlY291cGxlO1xuIiwiXCJ1c2Ugc3RyaWN0XCI7XG5cbnZhciBfY2xhc3NDYWxsQ2hlY2sgPSBmdW5jdGlvbiAoaW5zdGFuY2UsIENvbnN0cnVjdG9yKSB7IGlmICghKGluc3RhbmNlIGluc3RhbmNlb2YgQ29uc3RydWN0b3IpKSB7IHRocm93IG5ldyBUeXBlRXJyb3IoXCJDYW5ub3QgY2FsbCBhIGNsYXNzIGFzIGEgZnVuY3Rpb25cIik7IH0gfTtcblxuZXhwb3J0cy5fX2VzTW9kdWxlID0gdHJ1ZTtcbi8qKlxuICogQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICogQGNsYXNzXG4gKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGEgbmV3IGluc3RhbmNlIG9mIEVtaXR0ZXIuXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlcyBhIG5ldyBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICogdmFyIEVtaXR0ZXIgPSByZXF1aXJlKCdlbWl0dGVyJyk7XG4gKlxuICogdmFyIGVtaXR0ZXIgPSBuZXcgRW1pdHRlcigpO1xuICovXG5cbnZhciBFbWl0dGVyID0gKGZ1bmN0aW9uICgpIHtcbiAgZnVuY3Rpb24gRW1pdHRlcigpIHtcbiAgICBfY2xhc3NDYWxsQ2hlY2sodGhpcywgRW1pdHRlcik7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50LlxuICAgKiBAbWVtYmVyb2YhIEVtaXR0ZXIucHJvdG90eXBlXG4gICAqIEBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgLSBUaGUgZXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgLSBBIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGFkZC5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBBZGQgYW4gZXZlbnQgbGlzdGVuZXIgdG8gXCJmb29cIiBldmVudC5cbiAgICogZW1pdHRlci5vbignZm9vJywgbGlzdGVuZXIpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5vbiA9IGZ1bmN0aW9uIG9uKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgIC8vIFVzZSB0aGUgY3VycmVudCBjb2xsZWN0aW9uIG9yIGNyZWF0ZSBpdC5cbiAgICB0aGlzLl9ldmVudENvbGxlY3Rpb24gPSB0aGlzLl9ldmVudENvbGxlY3Rpb24gfHwge307XG5cbiAgICAvLyBVc2UgdGhlIGN1cnJlbnQgY29sbGVjdGlvbiBvZiBhbiBldmVudCBvciBjcmVhdGUgaXQuXG4gICAgdGhpcy5fZXZlbnRDb2xsZWN0aW9uW2V2ZW50XSA9IHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0gfHwgW107XG5cbiAgICAvLyBBcHBlbmRzIHRoZSBsaXN0ZW5lciBpbnRvIHRoZSBjb2xsZWN0aW9uIG9mIHRoZSBnaXZlbiBldmVudFxuICAgIHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0ucHVzaChsaXN0ZW5lcik7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogQWRkcyBhIGxpc3RlbmVyIHRvIHRoZSBjb2xsZWN0aW9uIGZvciB0aGUgc3BlY2lmaWVkIGV2ZW50IHRoYXQgd2lsbCBiZSBjYWxsZWQgb25seSBvbmNlLlxuICAgKiBAbWVtYmVyb2YhIEVtaXR0ZXIucHJvdG90eXBlXG4gICAqIEBmdW5jdGlvblxuICAgKiBAcGFyYW0ge1N0cmluZ30gZXZlbnQgLSBUaGUgZXZlbnQgbmFtZS5cbiAgICogQHBhcmFtIHtGdW5jdGlvbn0gbGlzdGVuZXIgLSBBIGxpc3RlbmVyIGZ1bmN0aW9uIHRvIGFkZC5cbiAgICogQHJldHVybnMge09iamVjdH0gUmV0dXJucyBhbiBpbnN0YW5jZSBvZiBFbWl0dGVyLlxuICAgKiBAZXhhbXBsZVxuICAgKiAvLyBXaWxsIGFkZCBhbiBldmVudCBoYW5kbGVyIHRvIFwiZm9vXCIgZXZlbnQgb25jZS5cbiAgICogZW1pdHRlci5vbmNlKCdmb28nLCBsaXN0ZW5lcik7XG4gICAqL1xuXG4gIEVtaXR0ZXIucHJvdG90eXBlLm9uY2UgPSBmdW5jdGlvbiBvbmNlKGV2ZW50LCBsaXN0ZW5lcikge1xuICAgIHZhciBzZWxmID0gdGhpcztcblxuICAgIGZ1bmN0aW9uIGZuKCkge1xuICAgICAgc2VsZi5vZmYoZXZlbnQsIGZuKTtcbiAgICAgIGxpc3RlbmVyLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgfVxuXG4gICAgZm4ubGlzdGVuZXIgPSBsaXN0ZW5lcjtcblxuICAgIHRoaXMub24oZXZlbnQsIGZuKTtcblxuICAgIHJldHVybiB0aGlzO1xuICB9O1xuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgbGlzdGVuZXIgZnJvbSB0aGUgY29sbGVjdGlvbiBmb3IgdGhlIHNwZWNpZmllZCBldmVudC5cbiAgICogQG1lbWJlcm9mISBFbWl0dGVyLnByb3RvdHlwZVxuICAgKiBAZnVuY3Rpb25cbiAgICogQHBhcmFtIHtTdHJpbmd9IGV2ZW50IC0gVGhlIGV2ZW50IG5hbWUuXG4gICAqIEBwYXJhbSB7RnVuY3Rpb259IGxpc3RlbmVyIC0gQSBsaXN0ZW5lciBmdW5jdGlvbiB0byByZW1vdmUuXG4gICAqIEByZXR1cm5zIHtPYmplY3R9IFJldHVybnMgYW4gaW5zdGFuY2Ugb2YgRW1pdHRlci5cbiAgICogQGV4YW1wbGVcbiAgICogLy8gUmVtb3ZlIGEgZ2l2ZW4gbGlzdGVuZXIuXG4gICAqIGVtaXR0ZXIub2ZmKCdmb28nLCBsaXN0ZW5lcik7XG4gICAqL1xuXG4gIEVtaXR0ZXIucHJvdG90eXBlLm9mZiA9IGZ1bmN0aW9uIG9mZihldmVudCwgbGlzdGVuZXIpIHtcblxuICAgIHZhciBsaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBEZWZpbmVzIGxpc3RlbmVycyB2YWx1ZS5cbiAgICBpZiAoIXRoaXMuX2V2ZW50Q29sbGVjdGlvbiB8fCAhKGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0pKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAoZm4sIGkpIHtcbiAgICAgIGlmIChmbiA9PT0gbGlzdGVuZXIgfHwgZm4ubGlzdGVuZXIgPT09IGxpc3RlbmVyKSB7XG4gICAgICAgIC8vIFJlbW92ZXMgdGhlIGdpdmVuIGxpc3RlbmVyLlxuICAgICAgICBsaXN0ZW5lcnMuc3BsaWNlKGksIDEpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgLy8gUmVtb3ZlcyBhbiBlbXB0eSBldmVudCBjb2xsZWN0aW9uLlxuICAgIGlmIChsaXN0ZW5lcnMubGVuZ3RoID09PSAwKSB7XG4gICAgICBkZWxldGUgdGhpcy5fZXZlbnRDb2xsZWN0aW9uW2V2ZW50XTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICAvKipcbiAgICogRXhlY3V0ZSBlYWNoIGl0ZW0gaW4gdGhlIGxpc3RlbmVyIGNvbGxlY3Rpb24gaW4gb3JkZXIgd2l0aCB0aGUgc3BlY2lmaWVkIGRhdGEuXG4gICAqIEBtZW1iZXJvZiEgRW1pdHRlci5wcm90b3R5cGVcbiAgICogQGZ1bmN0aW9uXG4gICAqIEBwYXJhbSB7U3RyaW5nfSBldmVudCAtIFRoZSBuYW1lIG9mIHRoZSBldmVudCB5b3Ugd2FudCB0byBlbWl0LlxuICAgKiBAcGFyYW0gey4uLk9iamVjdH0gZGF0YSAtIERhdGEgdG8gcGFzcyB0byB0aGUgbGlzdGVuZXJzLlxuICAgKiBAcmV0dXJucyB7T2JqZWN0fSBSZXR1cm5zIGFuIGluc3RhbmNlIG9mIEVtaXR0ZXIuXG4gICAqIEBleGFtcGxlXG4gICAqIC8vIEVtaXRzIHRoZSBcImZvb1wiIGV2ZW50IHdpdGggJ3BhcmFtMScgYW5kICdwYXJhbTInIGFzIGFyZ3VtZW50cy5cbiAgICogZW1pdHRlci5lbWl0KCdmb28nLCAncGFyYW0xJywgJ3BhcmFtMicpO1xuICAgKi9cblxuICBFbWl0dGVyLnByb3RvdHlwZS5lbWl0ID0gZnVuY3Rpb24gZW1pdChldmVudCkge1xuICAgIHZhciBfdGhpcyA9IHRoaXM7XG5cbiAgICBmb3IgKHZhciBfbGVuID0gYXJndW1lbnRzLmxlbmd0aCwgYXJncyA9IEFycmF5KF9sZW4gPiAxID8gX2xlbiAtIDEgOiAwKSwgX2tleSA9IDE7IF9rZXkgPCBfbGVuOyBfa2V5KyspIHtcbiAgICAgIGFyZ3NbX2tleSAtIDFdID0gYXJndW1lbnRzW19rZXldO1xuICAgIH1cblxuICAgIHZhciBsaXN0ZW5lcnMgPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBEZWZpbmVzIGxpc3RlbmVycyB2YWx1ZS5cbiAgICBpZiAoIXRoaXMuX2V2ZW50Q29sbGVjdGlvbiB8fCAhKGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50Q29sbGVjdGlvbltldmVudF0pKSB7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9XG5cbiAgICAvLyBDbG9uZSBsaXN0ZW5lcnNcbiAgICBsaXN0ZW5lcnMgPSBsaXN0ZW5lcnMuc2xpY2UoMCk7XG5cbiAgICBsaXN0ZW5lcnMuZm9yRWFjaChmdW5jdGlvbiAoZm4pIHtcbiAgICAgIHJldHVybiBmbi5hcHBseShfdGhpcywgYXJncyk7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfTtcblxuICByZXR1cm4gRW1pdHRlcjtcbn0pKCk7XG5cbi8qKlxuICogRXhwb3J0cyBFbWl0dGVyXG4gKi9cbmV4cG9ydHNbXCJkZWZhdWx0XCJdID0gRW1pdHRlcjtcbm1vZHVsZS5leHBvcnRzID0gZXhwb3J0c1tcImRlZmF1bHRcIl07Il19\n"
  },
  {
    "path": "index.css",
    "content": "body {\n  width: 100%;\n  height: 100%;\n}\n\n.slideout-menu {\n  position: fixed;\n  top: 0;\n  bottom: 0;\n  width: 256px;\n  min-height: 100vh;\n  overflow-y: scroll;\n  -webkit-overflow-scrolling: touch;\n  z-index: 0;\n  display: none;\n}\n\n.slideout-menu-left {\n  left: 0;\n}\n\n.slideout-menu-right {\n  right: 0;\n}\n\n.slideout-panel {\n  position: relative;\n  z-index: 1;\n  will-change: transform;\n  background-color: #FFF; /* A background-color is required */\n  min-height: 100vh;\n}\n\n.slideout-open,\n.slideout-open body,\n.slideout-open .slideout-panel {\n  overflow: hidden;\n}\n\n.slideout-open .slideout-menu {\n  display: block;\n}\n"
  },
  {
    "path": "index.js",
    "content": "'use strict';\n\n/**\n * Module dependencies\n */\nvar decouple = require('decouple');\nvar Emitter = require('emitter');\n\n/**\n * Privates\n */\nvar scrollTimeout;\nvar scrolling = false;\nvar doc = window.document;\nvar html = doc.documentElement;\nvar msPointerSupported = window.navigator.msPointerEnabled;\nvar touch = {\n  'start': msPointerSupported ? 'MSPointerDown' : 'touchstart',\n  'move': msPointerSupported ? 'MSPointerMove' : 'touchmove',\n  'end': msPointerSupported ? 'MSPointerUp' : 'touchend'\n};\nvar prefix = (function prefix() {\n  var regex = /^(Webkit|Khtml|Moz|ms|O)(?=[A-Z])/;\n  var styleDeclaration = doc.getElementsByTagName('script')[0].style;\n  for (var prop in styleDeclaration) {\n    if (regex.test(prop)) {\n      return '-' + prop.match(regex)[0].toLowerCase() + '-';\n    }\n  }\n  // Nothing found so far? Webkit does not enumerate over the CSS properties of the style object.\n  // However (prop in style) returns the correct value, so we'll have to test for\n  // the precence of a specific property\n  if ('WebkitOpacity' in styleDeclaration) { return '-webkit-'; }\n  if ('KhtmlOpacity' in styleDeclaration) { return '-khtml-'; }\n  return '';\n}());\nfunction extend(destination, from) {\n  for (var prop in from) {\n    if (from[prop]) {\n      destination[prop] = from[prop];\n    }\n  }\n  return destination;\n}\nfunction inherits(child, uber) {\n  child.prototype = extend(child.prototype || {}, uber.prototype);\n}\nfunction hasIgnoredElements(el) {\n  while (el.parentNode) {\n    if (el.getAttribute('data-slideout-ignore') !== null) {\n      return el;\n    }\n    el = el.parentNode;\n  }\n  return null;\n}\n\n/**\n * Slideout constructor\n */\nfunction Slideout(options) {\n  options = options || {};\n\n  // Sets default values\n  this._startOffsetX = 0;\n  this._currentOffsetX = 0;\n  this._opening = false;\n  this._moved = false;\n  this._opened = false;\n  this._preventOpen = false;\n\n  // Sets panel\n  this.panel = options.panel;\n  this.menu = options.menu;\n\n  // Sets options\n  this._touch = options.touch === undefined ? true : options.touch && true;\n  this._side = options.side || 'left';\n  this._easing = options.fx || options.easing || 'ease';\n  this._duration = parseInt(options.duration, 10) || 300;\n  this._tolerance = parseInt(options.tolerance, 10) || 70;\n  this._padding = this._translateTo = parseInt(options.padding, 10) || 256;\n  this._orientation = this._side === 'right' ? -1 : 1;\n  this._translateTo *= this._orientation;\n\n  // Sets  classnames\n  if (!this.panel.classList.contains('slideout-panel')) {\n    this.panel.classList.add('slideout-panel');\n  }\n  if (!this.panel.classList.contains('slideout-panel-' + this._side)) {\n    this.panel.classList.add('slideout-panel-' + this._side);\n  }\n  if (!this.menu.classList.contains('slideout-menu')) {\n    this.menu.classList.add('slideout-menu');\n  }\n  if (!this.menu.classList.contains('slideout-menu-' + this._side)) {\n    this.menu.classList.add('slideout-menu-' + this._side);\n  }\n\n  // Init touch events\n  if (this._touch) {\n    this._initTouchEvents();\n  }\n}\n\n/**\n * Inherits from Emitter\n */\ninherits(Slideout, Emitter);\n\n/**\n * Opens the slideout menu.\n */\nSlideout.prototype.open = function() {\n  var self = this;\n  this.emit('beforeopen');\n  if (!html.classList.contains('slideout-open')) {\n    html.classList.add('slideout-open');\n  }\n  this._setTransition();\n  this._translateXTo(this._translateTo);\n  this._opened = true;\n  setTimeout(function() {\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = '';\n    self.emit('open');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Closes slideout menu.\n */\nSlideout.prototype.close = function() {\n  var self = this;\n  if (!this.isOpen() && !this._opening) {\n    return this;\n  }\n  this.emit('beforeclose');\n  this._setTransition();\n  this._translateXTo(0);\n  this._opened = false;\n  setTimeout(function() {\n    html.classList.remove('slideout-open');\n    self.panel.style.transition = self.panel.style['-webkit-transition'] = self.panel.style[prefix + 'transform'] = self.panel.style.transform = '';\n    self.emit('close');\n  }, this._duration + 50);\n  return this;\n};\n\n/**\n * Toggles (open/close) slideout menu.\n */\nSlideout.prototype.toggle = function() {\n  return this.isOpen() ? this.close() : this.open();\n};\n\n/**\n * Returns true if the slideout is currently open, and false if it is closed.\n */\nSlideout.prototype.isOpen = function() {\n  return this._opened;\n};\n\n/**\n * Translates panel and updates currentOffset with a given X point\n */\nSlideout.prototype._translateXTo = function(translateX) {\n  this._currentOffsetX = translateX;\n  this.panel.style[prefix + 'transform'] = this.panel.style.transform = 'translateX(' + translateX + 'px)';\n  return this;\n};\n\n/**\n * Set transition properties\n */\nSlideout.prototype._setTransition = function() {\n  this.panel.style[prefix + 'transition'] = this.panel.style.transition = prefix + 'transform ' + this._duration + 'ms ' + this._easing;\n  return this;\n};\n\n/**\n * Initializes touch event\n */\nSlideout.prototype._initTouchEvents = function() {\n  var self = this;\n\n  /**\n   * Decouple scroll event\n   */\n  this._onScrollFn = decouple(doc, 'scroll', function() {\n    if (!self._moved) {\n      clearTimeout(scrollTimeout);\n      scrolling = true;\n      scrollTimeout = setTimeout(function() {\n        scrolling = false;\n      }, 250);\n    }\n  });\n\n  /**\n   * Prevents touchmove event if slideout is moving\n   */\n  this._preventMove = function(eve) {\n    if (self._moved) {\n      eve.preventDefault();\n    }\n  };\n\n  doc.addEventListener(touch.move, this._preventMove);\n\n  /**\n   * Resets values on touchstart\n   */\n  this._resetTouchFn = function(eve) {\n    if (typeof eve.touches === 'undefined') {\n      return;\n    }\n\n    self._moved = false;\n    self._opening = false;\n    self._startOffsetX = eve.touches[0].pageX;\n    self._preventOpen = (!self._touch || (!self.isOpen() && self.menu.clientWidth !== 0));\n  };\n\n  this.panel.addEventListener(touch.start, this._resetTouchFn);\n\n  /**\n   * Resets values on touchcancel\n   */\n  this._onTouchCancelFn = function() {\n    self._moved = false;\n    self._opening = false;\n  };\n\n  this.panel.addEventListener('touchcancel', this._onTouchCancelFn);\n\n  /**\n   * Toggles slideout on touchend\n   */\n  this._onTouchEndFn = function() {\n    if (self._moved) {\n      self.emit('translateend');\n      (self._opening && Math.abs(self._currentOffsetX) > self._tolerance) ? self.open() : self.close();\n    }\n    self._moved = false;\n  };\n\n  this.panel.addEventListener(touch.end, this._onTouchEndFn);\n\n  /**\n   * Translates panel on touchmove\n   */\n  this._onTouchMoveFn = function(eve) {\n    if (\n      scrolling ||\n      self._preventOpen ||\n      typeof eve.touches === 'undefined' ||\n      hasIgnoredElements(eve.target)\n    ) {\n      return;\n    }\n\n    var dif_x = eve.touches[0].clientX - self._startOffsetX;\n    var translateX = self._currentOffsetX = dif_x;\n\n    if (Math.abs(translateX) > self._padding) {\n      return;\n    }\n\n    if (Math.abs(dif_x) > 20) {\n\n      self._opening = true;\n\n      var oriented_dif_x = dif_x * self._orientation;\n\n      if (self._opened && oriented_dif_x > 0 || !self._opened && oriented_dif_x < 0) {\n        return;\n      }\n\n      if (!self._moved) {\n        self.emit('translatestart');\n      }\n\n      if (oriented_dif_x <= 0) {\n        translateX = dif_x + self._padding * self._orientation;\n        self._opening = false;\n      }\n\n      if (!(self._moved && html.classList.contains('slideout-open'))) {\n        html.classList.add('slideout-open');\n      }\n\n      self.panel.style[prefix + 'transform'] = self.panel.style.transform = 'translateX(' + translateX + 'px)';\n      self.emit('translate', translateX);\n      self._moved = true;\n    }\n\n  };\n\n  this.panel.addEventListener(touch.move, this._onTouchMoveFn);\n\n  return this;\n};\n\n/**\n * Enable opening the slideout via touch events.\n */\nSlideout.prototype.enableTouch = function() {\n  this._touch = true;\n  return this;\n};\n\n/**\n * Disable opening the slideout via touch events.\n */\nSlideout.prototype.disableTouch = function() {\n  this._touch = false;\n  return this;\n};\n\n/**\n * Destroy an instance of slideout.\n */\nSlideout.prototype.destroy = function() {\n  // Close before clean\n  this.close();\n\n  // Remove event listeners\n  doc.removeEventListener(touch.move, this._preventMove);\n  this.panel.removeEventListener(touch.start, this._resetTouchFn);\n  this.panel.removeEventListener('touchcancel', this._onTouchCancelFn);\n  this.panel.removeEventListener(touch.end, this._onTouchEndFn);\n  this.panel.removeEventListener(touch.move, this._onTouchMoveFn);\n  doc.removeEventListener('scroll', this._onScrollFn);\n\n  // Remove methods\n  this.open = this.close = function() {};\n\n  // Return the instance so it can be easily dereferenced\n  return this;\n};\n\n/**\n * Expose Slideout\n */\nmodule.exports = Slideout;\n"
  },
  {
    "path": "package.json",
    "content": "{\n  \"name\": \"slideout\",\n  \"repository\": \"git@github.com:mango/slideout.git\",\n  \"description\": \"A touch slideout navigation menu for your mobile web apps.\",\n  \"author\": \"Guille Paz <guille87paz@gmail.com>\",\n  \"version\": \"1.0.1\",\n  \"scripts\": {\n    \"build\": \"node browserify.js\",\n    \"test\": \"npm run build && istanbul cover _mocha\",\n    \"dist\": \"node browserify.js && uglifyjs ./dist/slideout.js -m -o ./dist/slideout.min.js\",\n    \"hint\": \"jshint index.js\"\n  },\n  \"dependencies\": {\n    \"decouple\": \"0.0.2\",\n    \"emitter\": \"git+https://github.com/Mango/emitter.git#0.0.7\"\n  },\n  \"devDependencies\": {\n    \"better-assert\": \"1.0.2\",\n    \"browserify\": \"13.1.1\",\n    \"coveralls\": \"2.11.15\",\n    \"istanbul\": \"0.4.5\",\n    \"jsdom\": \"9.8.3\",\n    \"jshint\": \"2.9.4\",\n    \"mocha\": \"3.1.2\",\n    \"uglify-js\": \"2.7.4\"\n  },\n  \"main\": \"index.js\",\n  \"keywords\": [\n    \"slideout\",\n    \"offcanvas\",\n    \"menu\",\n    \"touch\"\n  ],\n  \"license\": \"MIT\",\n  \"spm\": {\n    \"dependencies\": {\n      \"decouple\": \"0.0.2\",\n      \"emitter\": \"git+https://github.com/Mango/emitter.git#0.0.7\"\n    },\n    \"main\": \"index.js\"\n  },\n  \"filename\": \"slideout.min.js\",\n  \"autoupdate\": {\n    \"source\": \"git\",\n    \"target\": \"git://github.com/Mango/slideout.git\",\n    \"basePath\": \"dist\",\n    \"files\": [\n      \"*.js\"\n    ]\n  }\n}\n"
  },
  {
    "path": "test/index.html",
    "content": "<!doctype html>\n<!--[if IE 8]><html class=\"ie8 lt-ie10\"><![endif]-->\n<!--[if IE 9]><html class=\"ie9 lt-ie10\"><![endif]-->\n<!--[if gt IE 9]><!--><html lang=\"en\"><!--<![endif]-->\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta http-equiv=\"cleartype\" content=\"on\">\n    <meta name=\"MobileOptimized\" content=\"320\">\n    <meta name=\"HandheldFriendly\" content=\"True\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n    <link rel=\"stylesheet\" href=\"https://cdnjs.cloudflare.com/ajax/libs/mocha/1.13.0/mocha.min.css\">\n    <link rel=\"stylesheet\" href=\"test.css\">\n    <link rel=\"stylesheet\" href=\"../index.css\">\n    <title>Slideout tests</title>\n  </head>\n  <body>\n\n    <nav id=\"menu\" class=\"menu\">\n      <a href=\"https://github.com/mango/slideout\" target=\"_blank\">\n        <header class=\"menu-header\">\n          <span class=\"menu-header-title\">Tests</span>\n        </header>\n      </a>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n    </nav>\n\n    <main id=\"panel\" class=\"panel\">\n      <header class=\"panel-header\">\n        <button class=\"btn-hamburger js-slideout-toggle\"></button>\n        <h1 class=\"title\">Slideout.js</h1>\n      </header>\n\n      <section class=\"box\">\n        <h2 class=\"box-title\">Test</h2>\n        <div id=\"mocha\" class=\"box-content\"></div>\n      </section>\n\n      <footer class=\"panel-footer\">\n        <p>with <span class=\"heart\">❤</span> by <a href=\"https://getmango.com/en\" target=\"_blank\">Mango</a></p>\n      </footer>\n    </main>\n\n    <script src=\"https://cdnjs.cloudflare.com/ajax/libs/mocha/1.13.0/mocha.min.js\"></script>\n    <script>\n      mocha.setup('bdd');\n      var exports = null;\n      function assert(expr, msg) {\n        if (!expr) throw new Error(msg || 'failed');\n      }\n    </script>\n    <script src=\"../dist/slideout.js\"></script>\n    <script src=\"test.js\"></script>\n    <script>\n      window.onload = function() {\n        document.querySelector('.js-slideout-toggle').addEventListener('click', function() {\n          slideout.toggle();\n        });\n\n        document.querySelector('.menu').addEventListener('click', function(eve) {\n          if (eve.target.nodeName === 'A') { slideout.close(); }\n        });\n\n        var runner = mocha.run();\n      };\n    </script>\n  </body>\n</html>"
  },
  {
    "path": "test/index.right.html",
    "content": "<!doctype html>\n<!--[if IE 8]><html class=\"ie8 lt-ie10\"><![endif]-->\n<!--[if IE 9]><html class=\"ie9 lt-ie10\"><![endif]-->\n<!--[if gt IE 9]><!--><html lang=\"en\"><!--<![endif]-->\n  <head>\n    <meta charset=\"utf-8\">\n    <meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n    <meta http-equiv=\"cleartype\" content=\"on\">\n    <meta name=\"MobileOptimized\" content=\"320\">\n    <meta name=\"HandheldFriendly\" content=\"True\">\n    <meta name=\"apple-mobile-web-app-capable\" content=\"yes\">\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0, user-scalable=no\">\n    <link rel=\"stylesheet\" href=\"test.css\">\n    <link rel=\"stylesheet\" href=\"../index.css\">\n    <style>\n      .slideout-menu { text-align: right; }\n      .btn-hamburger { left: auto; right: 12px;}\n      .box { height: 1500px; }\n    </style>\n    <title>Slideout right tests</title>\n  </head>\n  <body>\n\n    <nav id=\"menu\" class=\"menu\">\n      <a href=\"https://github.com/mango/slideout\" target=\"_blank\">\n        <header class=\"menu-header\">\n          <span class=\"menu-header-title\">Tests</span>\n        </header>\n      </a>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n\n      <section class=\"menu-section\">\n        <h3 class=\"menu-section-title\">Docs</h3>\n        <ul class=\"menu-section-list\">\n          <li><a href=\"https://github.com/mango/slideout#installation\" target=\"_blank\">Installation</a></li>\n          <li><a href=\"https://github.com/mango/slideout#usage\" target=\"_blank\">Usage</a></li>\n          <li><a href=\"https://github.com/mango/slideout#api\" target=\"_blank\">API</a></li>\n          <li><a href=\"https://github.com/mango/slideout#npm-scripts\" target=\"_blank\">npm-scripts</a></li>\n        </ul>\n      </section>\n    </nav>\n\n    <main id=\"panel\" class=\"panel\">\n      <header class=\"panel-header\">\n        <button class=\"btn-hamburger js-slideout-toggle\"></button>\n        <h1 class=\"title\">Slideout.js</h1>\n      </header>\n\n      <section class=\"box\">\n        <h2 class=\"box-title\">Test</h2>\n        <div class=\"box-content\"></div>\n      </section>\n\n      <footer class=\"panel-footer\">\n        <p>with <span class=\"heart\">❤</span> by <a href=\"https://getmango.com/en\" target=\"_blank\">Mango</a></p>\n      </footer>\n    </main>\n    <script src=\"../dist/slideout.js\"></script>\n    <script>\n      window.onload = function() {\n        var slideout = new Slideout({\n          'panel': document.getElementById('panel'),\n          'menu': document.getElementById('menu'),\n          'side': 'right'\n        });\n\n        document.querySelector('.js-slideout-toggle').addEventListener('click', function() {\n          slideout.toggle();\n        });\n\n        document.querySelector('.menu').addEventListener('click', function(eve) {\n          if (eve.target.nodeName === 'A') { slideout.close(); }\n        });\n      };\n    </script>\n  </body>\n</html>\n"
  },
  {
    "path": "test/test.css",
    "content": "/*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:700}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type=button],input[type=reset],input[type=submit]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=number]::-webkit-inner-spin-button,input[type=number]::-webkit-outer-spin-button{height:auto}input[type=search]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type=search]::-webkit-search-cancel-button,input[type=search]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:700}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}\nhtml,\nbody {\n  font: 100%/1.4em 'Helvetica Neue', Helvetica, Arial, sans-serif;\n  margin: 0 auto;\n  color: #222;\n  -webkit-text-size-adjust: none;\n  -webkit-font-smoothing: antialiased;\n}\n\nbody,\n.panel {\n  background-color: #fff;\n}\n\n.menu {\n  background-color: #1D1F20;\n  background-image: linear-gradient(145deg, #1D1F20, #404348);\n}\n\na {\n  color: #4B5;\n  text-decoration: none;\n}\n\n.menu a {\n  color: #fff;\n}\n\n.menu a:hover {\n  text-decoration: underline;\n}\n\n.menu-header {\n  border-bottom: 1px solid #2a2d2f;\n  padding: 20px;\n  background-size: 32px;\n}\n\n.menu-header-title {\n  font-weight: 400;\n  letter-spacing: 0.5px;\n  margin: 0;\n}\n\n.menu-section {\n  margin: 25px 0;\n}\n\n.menu-section-title {\n  text-transform: uppercase;\n  color: #85888d;\n  font-weight: 200;\n  font-size: 13px;\n  letter-spacing: 1px;\n  padding: 0 20px;\n  margin:0;\n}\n\n.menu-section-list {\n  padding:0;\n  margin: 10px 0;\n  list-style:none;\n}\n\n.menu-section-list a {\n  display: block;\n  padding: 10px 20px;\n}\n\n.panel {\n  text-align: center;\n  padding-top: 5px;\n  min-height: 100%;\n}\n\n#mocha {\n  text-align: left;\n  margin:0 !important;\n}\n\n#mocha-stats {\n  top: 70px;\n}\n\n/**\n * Header\n */\n.panel-header {\n  margin: 120px auto 55px;\n}\n\n.title {\n  font-size: 3.2em;\n  line-height: 1em;\n  margin: 0 0 15px;\n  color: #4B5;\n  font-weight: 400;\n}\n\n/**\n * hamburger\n */\n.btn-hamburger {\n  border: none;\n  position: absolute;\n  top: 12px;\n  left: 12px;\n  outline:none;\n  background: url('assets/menu.png') no-repeat center;\n  width: 50px;\n  height: 50px;\n}\n\n/**\n * Boxes\n */\n.box {\n  border: 1px solid #4b5;\n  border-radius: 4px;\n  text-align: left;\n  margin: 50px 10px;\n  position: relative;\n}\n\n.box:before,\n.box:after {\n  content: ' ';\n  display: inline-block;\n  width: 1px;\n  height: 50px;\n  border-left: 1px solid #4b5;\n  position: absolute;\n  left: 50%;\n}\n\n.box:before {\n  top: -50px;\n}\n\n.box:after {\n  bottom: -50px;\n}\n\n.box-title {\n  margin: 0;\n  padding:10px 20px;\n  border-bottom: 1px solid #4b5;\n  color: #4b5;\n  font-size: 1.2em;\n  font-weight: 400;\n}\n\n.box-content {\n  padding:20px;\n  background-color: #f8f8f8;\n}\n\n/**\n * Medium Screens\n */\n@media all and (min-width:40em) {\n\n  .btn-hamburger {\n    top: 20px;\n    left: 30px;\n  }\n\n  .panel-header {\n    margin-top: 40px;\n    width: 455px;\n  }\n\n  .title {\n    font-size: 4.2em;\n  }\n}\n\n/**\n * Large Screens\n */\n@media all and (min-width: 54em) {\n  .box {\n    width: 70%;\n    max-width: 1200px;\n    margin: 50px auto;\n  }\n}\n\n/**\n * Footer\n */\n.panel-footer {\n  margin: 10px auto 20px;\n}\n\n.panel-footer p {\n  padding-bottom: 20px;\n}\n\n.heart {\n  font-style: normal;\n  font-weight: 500;\n  color: #c0392b;\n  text-decoration: none;\n}\n"
  },
  {
    "path": "test/test.js",
    "content": "if (exports) {\n  var fs = require('fs');\n  var jsdom = require('jsdom').jsdom;\n  var html = fs.readFileSync('./test/index.html', 'utf-8');\n  var document = jsdom(html);\n  window = document.defaultView;\n  var Slideout = require('../');\n  var assert = require('better-assert');\n}\n\nvar doc = window.document;\nvar beforeopenEvent = false;\nvar openEvent = false;\nvar beforecloseEvent = false;\nvar closeEvent = false;\nvar slideout = new Slideout({\n  'panel': doc.getElementById('panel'),\n  'menu': doc.getElementById('menu'),\n});\n\nslideout\n  .on('beforeopen', function() {\n    beforeopenEvent = true;\n  })\n  .on('open', function() {\n    openEvent = true;\n  })\n  .on('beforeclose', function() {\n    beforecloseEvent = true;\n  })\n  .on('close', function() {\n    closeEvent = true;\n  });\n\ndescribe('Slideout', function () {\n\n  it('should be defined.', function () {\n    assert(Slideout !== undefined);\n  });\n\n  it('should be a function.', function () {\n    assert(typeof Slideout === 'function');\n  });\n\n  it('should return a new instance.', function () {\n    assert(slideout instanceof Slideout);\n  });\n\n  describe('should have the following methods:', function () {\n    var methods = [\n      'open',\n      'close',\n      'toggle',\n      'isOpen',\n      '_initTouchEvents',\n      '_translateXTo',\n      '_setTransition',\n      'on',\n      'once',\n      'off',\n      'emit'\n    ];\n    var i = 0;\n    var len = methods.length;\n    for (i; i < len; i += 1) {\n      (function (i) {\n        it('.' + methods[i] + '()', function (done) {\n          assert(typeof slideout[methods[i]] === 'function');\n          done()\n        });\n      }(i));\n    }\n  });\n\n  describe('should define the following properties:', function () {\n    var properties = [\n      'panel',\n      'menu',\n      '_startOffsetX',\n      '_currentOffsetX',\n      '_opening',\n      '_moved',\n      '_opened',\n      '_easing',\n      '_duration',\n      '_tolerance',\n      '_padding',\n      '_touch',\n      '_side'\n    ];\n    var i = 0;\n    var len = properties.length;\n    for (i; i < len; i += 1) {\n      (function (i) {\n        it('.' + properties[i] + '()', function (done) {\n          assert(slideout[properties[i]] !== undefined);\n          done()\n        });\n      }(i));\n    }\n  });\n\n  it('should add classnames to panel and menu DOM elements.', function () {\n    assert(slideout.panel.className.search('slideout-panel') !== -1);\n    assert(slideout.panel.className.search('slideout-panel-left') !== -1);\n    assert(slideout.menu.className.search('slideout-menu') !== -1);\n    assert(slideout.menu.className.search('slideout-menu-left') !== -1);\n  });\n\n  describe('.open()', function () {\n    it('should add \"slideout-open\" classname to HTML.', function () {\n      assert(doc.documentElement.className.search('slideout-open') === -1);\n      slideout.open();\n      assert(doc.documentElement.className.search('slideout-open') !== -1);\n    });\n\n    it('should translateX the panel to the given padding.', function () {\n      assert(slideout.panel.style.transform === 'translateX(256px)');\n      assert(slideout.panel.style.transition.search(/transform 300ms ease/) !== -1);\n    });\n\n    it('should set _opened to true.', function () {\n      assert(slideout._opened === true);\n    });\n\n    it('should emit \"beforeopen\" event.', function () {\n      assert(beforeopenEvent === true);\n    });\n\n    it('should emit \"open\" event.', function (done) {\n      setTimeout(function(){\n        assert(openEvent === true);\n        done();\n      }, 400);\n\n    });\n  });\n\n  describe('.isOpen()', function () {\n    it('should return true if the slideout is opened.', function () {\n      assert(slideout.isOpen());\n    });\n  });\n\n  describe('.close()', function () {\n    it('should remove \"slideout-open\" classname to HTML.', function (done) {\n      assert(doc.documentElement.className.search('slideout-open') !== -1);\n      slideout.close();\n      setTimeout(function(){\n        assert(doc.documentElement.className.search('slideout-open') === -1);\n        done();\n      }, 350);\n\n    });\n\n    it('should translateX the panel to 0.', function () {\n      assert(slideout.panel.style.transform === '');\n      assert(slideout.panel.style.transition === '');\n    });\n\n    it('should set _opened to false.', function () {\n      assert(slideout._opened === false);\n    });\n\n    it('should emit \"beforeclose\" event.', function () {\n      assert(beforecloseEvent === true);\n    });\n\n    it('should emit \"close\" event.', function () {\n      assert(closeEvent === true);\n    });\n  });\n\n  describe('.toggle()', function () {\n    it('should show the slideout if it is not opened.', function (done) {\n      assert(doc.documentElement.className.search('slideout-open') === -1);\n      slideout.toggle();\n      assert(doc.documentElement.className.search('slideout-open') !== -1);\n      slideout.toggle();\n      setTimeout(function(){\n        assert(doc.documentElement.className.search('slideout-open') === -1);\n        done();\n      }, 350);\n    });\n  });\n\n  describe('.destroy()', function() {\n    it('should destroy the instance internals allowing a new one to be created in it\\'s place.', function(){\n      slideout.destroy();\n      slideout = new Slideout({\n        'panel': doc.getElementById('panel'),\n        'menu': doc.getElementById('menu')\n      });\n      slideout.open();\n      setTimeout(function(){ slideout.close(); }, 750);\n    });\n  });\n});\n"
  }
]