Просмотр исходного кода

Merge pull request #41 from transloadit/build-feedback

Build feedback
Kevin van Zonneveld 9 лет назад
Родитель
Сommit
6ca0f5f685

+ 2 - 0
.gitignore

@@ -13,3 +13,5 @@ website/public/
 website/.deploy*/
 website/.deploy*/
 website/src/_drafts
 website/src/_drafts
 website/src/examples/**/static/js/app.js
 website/src/examples/**/static/js/app.js
+
+website/themes/uppy/source/js/uppy.js

+ 1 - 1
.travis.yml

@@ -15,7 +15,7 @@ script:
 after_success:
 after_success:
   - git config --global user.name 'Uppy Bot'
   - git config --global user.name 'Uppy Bot'
   - git config --global user.email 'uppybot@uppyjs.io'
   - git config --global user.email 'uppybot@uppyjs.io'
-  - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && make website-deploy ghpages_url=${GHPAGES_URL}
+  - test $TRAVIS_PULL_REQUEST == "false" && test $TRAVIS_BRANCH == "master" && npm run web:deploy
 
 
 env:
 env:
   global:
   global:

+ 0 - 24
Makefile

@@ -1,24 +0,0 @@
-SHELL          := /usr/bin/env bash
-ghpages_repo   := "transloadit/uppy"
-ghpages_branch := "gh-pages"
-ghpages_url    := "git@github.com:$(ghpages_repo).git"
-
-.PHONY: web-install
-web-install:
-	npm run website:install
-
-.PHONY: web-build
-web-build:
-	npm run website:build
-
-.PHONY: web-preview
-web-preview:
-	npm run website:preview
-
-.PHONY: web-deploy
-web-deploy:
-	npm run website:deploy
-
-.PHONY: watch
-watch:
-	npm run watch:examples

+ 2 - 53
README.md

@@ -4,57 +4,6 @@ A work in progress - nothing to see here.
 
 
 Interesting places if you want to dig in:
 Interesting places if you want to dig in:
 
 
- - Architecture in [`website/src/api/index.md`](https://github.com/transloadit/uppy/blob/master/website/src/api/index.md)
- - Contributor's guide in [`website/src/guide/contributing.md`](https://github.com/transloadit/uppy/blob/master/src/guide/contributing.md)
+ - Architecture in [`website/src/api/index.md`](website/src/api/index.md)
+ - Contributor's guide in [`website/src/guide/contributing.md`](src/guide/contributing.md)
  - [Open issues](https://github.com/transloadit/uppy/milestones/Minimum%20Viable%20Product) before having a Minimum Valuable Product. 
  - [Open issues](https://github.com/transloadit/uppy/milestones/Minimum%20Viable%20Product) before having a Minimum Valuable Product. 
-
-## Uppy Development
-
-First clone and install the project:
-
-```bash
-git clone git@github.com:transloadit/uppy.git
-cd uppy
-npm install
-```
-
-Our website's examples section is also our playground. To get it to run locally type:
-
-```bash
-make website-preview
-```
-
-## Website Development
-
-We keep the [uppyjs.io](http://uppyjs.io) website in `./website` for so it's easy to keep docs & code in sync as we're still iterating at high velocity. For those reading this screaming murder, [HashiCorp does this](https://github.com/hashicorp/terraform/tree/master/website) for all their projects, and it's working well for them on a scale vastly more impressive than :dog:'s.
-
-The site is built with [Hexo](http://hexo.io/), and Travis automatically deploys this onto GitHub Pages (it overwrites the [`gh-pages`](https://github.com/transloadit/uppy/tree/gh-pages) branch at every deploy).
-
-Content is written in Markdown and located in [`./website/src`](https://github.com/transloadit/uppy/tree/master/website/src). Feel free to fork & hack!  
-
-`./website/update.js` is called during website builds to inject the Uppy versions & filesizes into the documentation. `website` in an independent folder (with e.g. its own package.json) and so it cannot rely on anything from the root project directly. `update.js` is the bridge that explicitly makes information available by injecting it into the website.
-
-It's recommended to exclude `./website/public/` from your editor if you want efficient searches.
-
-For local previews on http://127.0.0.1:4000 type:
-
-```bash
-make website-preview
-```
-
-## FAQ
-
-### Why does your site look like vuejs.org?
-
-The website is currently a clone of Yuxi Evan You's wonderful [Vue.js](http://vuejs.org/) website ([view license](website/VUEORG_LICENSE)) - just so we can hit the ground running in terms of Haxo boilerplate, etc. Obviously as soon as possible, we'll start rolling out our own layout & content and make this place our own. We'll keep the Vue website MIT license & credit in the footer in tact of course.
-
-### What does Travis do?
-
-Travis should:
-
-- [x] check out code 
-- [x] build project
-- [ ] run unit tests
-- [ ] run acceptance tests
-- [x] copy/install the built project into any `examples/*/`
-- [x] deploy the examples to our hackathon S3 bucket in a folder named by branch (http://hackathon.transloadit.com/uppy/master/index.html), so we can all play with the current state of the project & examples per branch, without installing everything locally.

+ 10 - 1
bin/build-css

@@ -1,3 +1,12 @@
-#!/bin/bash
+#!/usr/bin/env bash
+set -o pipefail
+set -o errexit
+set -o nounset
+# set -o xtrace
+
+# Set magic variables for current file & dir
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
 
 
 node_modules/.bin/node-sass src/scss/index.scss -o dist/uppy.css
 node_modules/.bin/node-sass src/scss/index.scss -o dist/uppy.css

+ 10 - 1
bin/build-umd

@@ -1,4 +1,13 @@
-#!/bin/bash
+#!/usr/bin/env bash
+set -o pipefail
+set -o errexit
+set -o nounset
+# set -o xtrace
+
+# Set magic variables for current file & dir
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
 
 
 SRC="src/index.js"
 SRC="src/index.js"
 OUT="uppy.js"
 OUT="uppy.js"

+ 10 - 1
bin/test

@@ -1,4 +1,13 @@
-#!/bin/bash
+#!/usr/bin/env bash
+set -o pipefail
+set -o errexit
+set -o nounset
+# set -o xtrace
+
+# Set magic variables for current file & dir
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
 
 
 # Move into a known directory
 # Move into a known directory
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
 DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

+ 42 - 0
bin/web-deploy

@@ -0,0 +1,42 @@
+#!/usr/bin/env bash
+set -o pipefail
+set -o errexit
+set -o nounset
+# set -o xtrace
+
+# Set magic variables for current file & dir
+__dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
+__file="${__dir}/$(basename "${BASH_SOURCE[0]}")"
+__base="$(basename ${__file} .sh)"
+
+ghpages_repo=${GHPAGES_REPO:-"transloadit/uppy"}
+ghpages_branch=${GHPAGES_BRANCH:-"gh-pages"}
+ghpages_url=${GHPAGES_URL:-"git@github.com:${ghpages_repo}.git"}
+
+echo "--> Deploying to GitHub pages.."
+mkdir -p /tmp/deploy-${ghpages_repo}
+
+# Custom steps
+rsync \
+  --archive \
+  --delete \
+  --exclude=.git* \
+  --exclude=node_modules \
+  --exclude=lib \
+  --itemize-changes \
+  --checksum \
+  --no-times \
+  --no-group \
+  --no-motd \
+  --no-owner \
+./website/public/ /tmp/deploy-${ghpages_repo}
+
+echo 'This branch is just a deploy target. Do not edit. You changes will be lost.' > /tmp/deploy-${ghpages_repo}/README.md
+
+cd /tmp/deploy-${ghpages_repo} \
+  && git init && git checkout -B ${ghpages_branch} && git add --all . \
+  && git commit -nm "Update ${ghpages_repo} website by $${USER}" \
+  && (git remote add origin ${ghpages_url}|| true)  \
+  && git push origin ${ghpages_branch}:refs/heads/${ghpages_branch} --force
+
+rm -rf /tmp/deploy-${ghpages_repo}

+ 0 - 29
bin/website-deploy

@@ -1,29 +0,0 @@
-#!/bin/bash
-
-echo "--> Deploying to GitHub pages.."
-mkdir -p /tmp/deploy-$(ghpages_repo)
-
-# Custom steps
-rsync \
-  --archive \
-  --delete \
-  --exclude=.git* \
-  --exclude=node_modules \
-  --exclude=lib \
-  --itemize-changes \
-  --checksum \
-  --no-times \
-  --no-group \
-  --no-motd \
-  --no-owner \
-./website/public/ /tmp/deploy-$(ghpages_repo)
-
-echo 'This branch is just a deploy target. Do not edit. You changes will be lost.' > /tmp/deploy-$(ghpages_repo)/README.md
-
-cd /tmp/deploy-$(ghpages_repo) \
-  && git init && git checkout -B $(ghpages_branch) && git add --all . \
-  && git commit -nm "Update $(ghpages_repo) website by $${USER}" \
-  && (git remote add origin $(ghpages_url)|| true)  \
-  && git push origin $(ghpages_branch):refs/heads/$(ghpages_branch) --force
-
-rm -rf /tmp/deploy-$(ghpages_repo)

+ 9 - 7
package.json

@@ -4,22 +4,24 @@
   "description": "Almost as cute as a Puppy :dog:",
   "description": "Almost as cute as a Puppy :dog:",
   "main": "src/index.js",
   "main": "src/index.js",
   "scripts": {
   "scripts": {
-    "build": "npm run build:lib && npm run build:umd && npm run build:umd:min && npm run build:css",
     "build:css": "bin/build-css",
     "build:css": "bin/build-css",
     "build:lib": "babel src -d lib --stage 0",
     "build:lib": "babel src -d lib --stage 0",
-    "build:umd": "./bin/build-umd",
     "build:umd:min": "./bin/build-umd",
     "build:umd:min": "./bin/build-umd",
+    "build:umd": "./bin/build-umd",
+    "build": "npm run build:lib && npm run build:umd && npm run build:umd:min && npm run build:css",
     "clean": "rm -rf lib && rm -rf dist",
     "clean": "rm -rf lib && rm -rf dist",
     "lint": "eslint src/**/*.js",
     "lint": "eslint src/**/*.js",
     "server": "browser-sync start --config .browsersync.js",
     "server": "browser-sync start --config .browsersync.js",
-    "test": "bin/test",
     "test:phantom": "zuul test/spec/upload.js --phantom",
     "test:phantom": "zuul test/spec/upload.js --phantom",
+    "test": "bin/test",
     "watch:css": "nodemon -e src/scss -x \"npm run build:css\"",
     "watch:css": "nodemon -e src/scss -x \"npm run build:css\"",
-    "watch:examples": "cd website && node watch.js",
+    "watch:examples": "cd website && node watch-examples.js",
     "watch:js": "nodemon --watch src -e js --ignore src/scss -x \"npm run build:lib\"",
     "watch:js": "nodemon --watch src -e js --ignore src/scss -x \"npm run build:lib\"",
-    "website:build": "echo \"--> Building site..\" && cd website && node update.js && ./node_modules/.bin/hexo generate",
-    "website:install": "echo \"--> Installing dependencies\" && cd website && npm install",
-    "website:preview": "npm run website:build && cd website && ./node_modules/.bin/hexo server --debug"
+    "web:build": "cd website && node update.js && ./node_modules/.bin/hexo generate",
+    "web:deploy": "npm run web:install && npm run web:build && ./bin/web-deploy",
+    "web:install": "cd website && npm install",
+    "web:preview": "cd website && ./node_modules/.bin/hexo server --debug",
+    "web": "npm run web:install && npm run web:build && npm run web:preview"
   },
   },
   "repository": {
   "repository": {
     "type": "git",
     "type": "git",

+ 1 - 0
website/package.json

@@ -21,6 +21,7 @@
     "hexo-util": "^0.2.1"
     "hexo-util": "^0.2.1"
   },
   },
   "devDependencies": {
   "devDependencies": {
+    "node-notifier": "^4.4.0",
     "browserify": "^12.0.1",
     "browserify": "^12.0.1",
     "chalk": "^1.1.1",
     "chalk": "^1.1.1",
     "glob": "^6.0.1",
     "glob": "^6.0.1",

+ 0 - 32
website/src/examples/dragdrop/index.html

@@ -1,32 +0,0 @@
-  <!-- Playground styles -->
-  <link rel="stylesheet" href="static/css/style.css">
-
-  <!-- Basic Uppy styles -->
-  <link rel="stylesheet" href="static/css/uppy.css">
-
-        <form id="upload-target" class="UppyDragDrop" method="post" action="/" enctype="multipart/form-data">
-            <svg class="UppyDragDrop-puppy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125" enable-background="new 0 0 100 100"><path d="M16.582 21.3L-.085 62.713l32.94 13.295zM99.915 62.714L66.975 76.01 83.25 21.3zM50.917 68.117L62.443 56.59H37.386l11.527 11.526v5.905l-3.063 3.32 1.474 1.36 2.59-2.807 2.59 2.807 1.475-1.358-3.063-3.32zM66.976 41.415c-3.972 0-7.193-3.22-7.193-7.193 0-3.973 3.222-7.193 7.193-7.193 3.974 0 7.193 3.22 7.193 7.192 0 3.973-3.22 7.193-7.194 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.6-1.337-1.338-1.337zM32.854 41.415c-3.973 0-7.193-3.22-7.193-7.193 0-3.973 3.22-7.193 7.194-7.193 3.973 0 7.192 3.22 7.192 7.192 0 3.973-3.22 7.193-7.192 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.598-1.337-1.337-1.337z"/></svg>          <div>
-            <input id="UppyDragDrop-input" class="UppyDragDrop-input" type="file" name="files[]" data-multiple-caption="{count} files selected" multiple />
-            <label class="UppyDragDrop-label" for="UppyDragDrop-input"><strong>Choose a file</strong><span class="UppyDragDrop-dragText"> or drag it here</span>.</label>
-            <!-- <button class="UppyDragDrop-btn" type="submit">Upload</button> -->
-          </div>
-          <div class="UppyDragDrop-status"></div>
-        </form>
-
-        <small>Puppy icon by Jorge Fernandez del Castillo Gomez <br>from the Noun Project</small>
-
-
-
-<!-- Include the bundled app.js client -->
-<script src="static/js/app.js"></script>
-
-<!-- Add the branch name to the <title> and <h1> of this page -->
-<script>
-  var branch        = location.pathname.split('/')[2] || 'local-unknown';
-  var elTitle       = document.querySelector('title');
-  var elH1          = document.querySelector('h1');
-  var title         = 'You are reviewing branch: ' + branch;
-  elTitle.innerHTML = title;
-  elH1.innerHTML    = title;
-</script>
-</html>

+ 0 - 13
website/src/examples/dragdrop/package.json

@@ -1,13 +0,0 @@
-{
-  "name": "playground",
-  "version": "1.0.0",
-  "description": "",
-  "main": "index.js",
-  "scripts": {
-    "build": "../../node_modules/.bin/browserify src/js/app.js -o static/js/app.js -t [ babelify ]",
-    "watch": "../../node_modules/.bin/watchify src/js/app.js -o static/js/app.js",
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "author": "",
-  "license": "ISC"
-}

+ 0 - 0
website/src/examples/dragdrop/static/css/.empty


+ 0 - 427
website/src/examples/dragdrop/static/css/normalize.css

@@ -1,427 +0,0 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- *    user zoom.
- */
-
-html {
-  font-family: sans-serif; /* 1 */
-  -ms-text-size-adjust: 100%; /* 2 */
-  -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
-  margin: 0;
-}
-
-/* HTML5 display definitions
-   ========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-menu,
-nav,
-section,
-summary {
-  display: block;
-}
-
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-
-audio,
-canvas,
-progress,
-video {
-  display: inline-block; /* 1 */
-  vertical-align: baseline; /* 2 */
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
-  display: none;
-  height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
-  display: none;
-}
-
-/* Links
-   ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
-  background-color: transparent;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
-  outline: 0;
-}
-
-/* Text-level semantics
-   ========================================================================== */
-
-/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
- */
-
-abbr[title] {
-  border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
- */
-
-b,
-strong {
-  font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari and Chrome.
- */
-
-dfn {
-  font-style: italic;
-}
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-
-h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
-  background: #ff0;
-  color: #000;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
-  font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
-  font-size: 75%;
-  line-height: 0;
-  position: relative;
-  vertical-align: baseline;
-}
-
-sup {
-  top: -0.5em;
-}
-
-sub {
-  bottom: -0.25em;
-}
-
-/* Embedded content
-   ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-
-img {
-  border: 0;
-}
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
-  overflow: hidden;
-}
-
-/* Grouping content
-   ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
- */
-
-figure {
-  margin: 1em 40px;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-  height: 0;
-}
-
-/**
- * Contain overflow in all browsers.
- */
-
-pre {
-  overflow: auto;
-}
-
-/**
- * Address odd `em`-unit font size rendering in all browsers.
- */
-
-code,
-kbd,
-pre,
-samp {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-
-/* Forms
-   ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
-
-/**
- * 1. Correct color not being inherited.
- *    Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
-  color: inherit; /* 1 */
-  font: inherit; /* 2 */
-  margin: 0; /* 3 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
-  overflow: visible;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
-
-button,
-select {
-  text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- *    and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- *    `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
-  -webkit-appearance: button; /* 2 */
-  cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
-  cursor: default;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-  border: 0;
-  padding: 0;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
-  line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
-  box-sizing: border-box; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
-  height: auto;
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
- *    (include `-moz` to future-proof).
- */
-
-input[type="search"] {
-  -webkit-appearance: textfield; /* 1 */
-  -moz-box-sizing: content-box;
-  -webkit-box-sizing: content-box; /* 2 */
-  box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
-  border: 1px solid #c0c0c0;
-  margin: 0 2px;
-  padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
-  border: 0; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
- */
-
-textarea {
-  overflow: auto;
-}
-
-/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
-  font-weight: bold;
-}
-
-/* Tables
-   ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-td,
-th {
-  padding: 0;
-}

+ 0 - 418
website/src/examples/dragdrop/static/css/skeleton.css

@@ -1,418 +0,0 @@
-/*
-* Skeleton V2.0.4
-* Copyright 2014, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 12/29/2014
-*/
-
-
-/* Table of contents
-––––––––––––––––––––––––––––––––––––––––––––––––––
-- Grid
-- Base Styles
-- Typography
-- Links
-- Buttons
-- Forms
-- Lists
-- Code
-- Tables
-- Spacing
-- Utilities
-- Clearing
-- Media Queries
-*/
-
-
-/* Grid
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.container {
-  position: relative;
-  width: 100%;
-  max-width: 960px;
-  margin: 0 auto;
-  padding: 0 20px;
-  box-sizing: border-box; }
-.column,
-.columns {
-  width: 100%;
-  float: left;
-  box-sizing: border-box; }
-
-/* For devices larger than 400px */
-@media (min-width: 400px) {
-  .container {
-    width: 85%;
-    padding: 0; }
-}
-
-/* For devices larger than 550px */
-@media (min-width: 550px) {
-  .container {
-    width: 80%; }
-  .column,
-  .columns {
-    margin-left: 4%; }
-  .column:first-child,
-  .columns:first-child {
-    margin-left: 0; }
-
-  .one.column,
-  .one.columns                    { width: 4.66666666667%; }
-  .two.columns                    { width: 13.3333333333%; }
-  .three.columns                  { width: 22%;            }
-  .four.columns                   { width: 30.6666666667%; }
-  .five.columns                   { width: 39.3333333333%; }
-  .six.columns                    { width: 48%;            }
-  .seven.columns                  { width: 56.6666666667%; }
-  .eight.columns                  { width: 65.3333333333%; }
-  .nine.columns                   { width: 74.0%;          }
-  .ten.columns                    { width: 82.6666666667%; }
-  .eleven.columns                 { width: 91.3333333333%; }
-  .twelve.columns                 { width: 100%; margin-left: 0; }
-
-  .one-third.column               { width: 30.6666666667%; }
-  .two-thirds.column              { width: 65.3333333333%; }
-
-  .one-half.column                { width: 48%; }
-
-  /* Offsets */
-  .offset-by-one.column,
-  .offset-by-one.columns          { margin-left: 8.66666666667%; }
-  .offset-by-two.column,
-  .offset-by-two.columns          { margin-left: 17.3333333333%; }
-  .offset-by-three.column,
-  .offset-by-three.columns        { margin-left: 26%;            }
-  .offset-by-four.column,
-  .offset-by-four.columns         { margin-left: 34.6666666667%; }
-  .offset-by-five.column,
-  .offset-by-five.columns         { margin-left: 43.3333333333%; }
-  .offset-by-six.column,
-  .offset-by-six.columns          { margin-left: 52%;            }
-  .offset-by-seven.column,
-  .offset-by-seven.columns        { margin-left: 60.6666666667%; }
-  .offset-by-eight.column,
-  .offset-by-eight.columns        { margin-left: 69.3333333333%; }
-  .offset-by-nine.column,
-  .offset-by-nine.columns         { margin-left: 78.0%;          }
-  .offset-by-ten.column,
-  .offset-by-ten.columns          { margin-left: 86.6666666667%; }
-  .offset-by-eleven.column,
-  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }
-
-  .offset-by-one-third.column,
-  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }
-  .offset-by-two-thirds.column,
-  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }
-
-  .offset-by-one-half.column,
-  .offset-by-one-half.columns     { margin-left: 52%; }
-
-}
-
-
-/* Base Styles
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/* NOTE
-html is set to 62.5% so that all the REM measurements throughout Skeleton
-are based on 10px sizing. So basically 1.5rem = 15px :) */
-html {
-  font-size: 62.5%; }
-body {
-  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
-  line-height: 1.6;
-  font-weight: 400;
-  font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #222; }
-
-
-/* Typography
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-h1, h2, h3, h4, h5, h6 {
-  margin-top: 0;
-  margin-bottom: 2rem;
-  font-weight: 300; }
-h1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}
-h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
-h3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }
-h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
-h5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }
-h6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }
-
-/* Larger than phablet */
-@media (min-width: 550px) {
-  h1 { font-size: 5.0rem; }
-  h2 { font-size: 4.2rem; }
-  h3 { font-size: 3.6rem; }
-  h4 { font-size: 3.0rem; }
-  h5 { font-size: 2.4rem; }
-  h6 { font-size: 1.5rem; }
-}
-
-p {
-  margin-top: 0; }
-
-
-/* Links
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-a {
-  color: #1EAEDB; }
-a:hover {
-  color: #0FA0CE; }
-
-
-/* Buttons
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.button,
-button,
-input[type="submit"],
-input[type="reset"],
-input[type="button"] {
-  display: inline-block;
-  height: 38px;
-  padding: 0 30px;
-  color: #555;
-  text-align: center;
-  font-size: 11px;
-  font-weight: 600;
-  line-height: 38px;
-  letter-spacing: .1rem;
-  text-transform: uppercase;
-  text-decoration: none;
-  white-space: nowrap;
-  background-color: transparent;
-  border-radius: 4px;
-  border: 1px solid #bbb;
-  cursor: pointer;
-  box-sizing: border-box; }
-.button:hover,
-button:hover,
-input[type="submit"]:hover,
-input[type="reset"]:hover,
-input[type="button"]:hover,
-.button:focus,
-button:focus,
-input[type="submit"]:focus,
-input[type="reset"]:focus,
-input[type="button"]:focus {
-  color: #333;
-  border-color: #888;
-  outline: 0; }
-.button.button-primary,
-button.button-primary,
-input[type="submit"].button-primary,
-input[type="reset"].button-primary,
-input[type="button"].button-primary {
-  color: #FFF;
-  background-color: #33C3F0;
-  border-color: #33C3F0; }
-.button.button-primary:hover,
-button.button-primary:hover,
-input[type="submit"].button-primary:hover,
-input[type="reset"].button-primary:hover,
-input[type="button"].button-primary:hover,
-.button.button-primary:focus,
-button.button-primary:focus,
-input[type="submit"].button-primary:focus,
-input[type="reset"].button-primary:focus,
-input[type="button"].button-primary:focus {
-  color: #FFF;
-  background-color: #1EAEDB;
-  border-color: #1EAEDB; }
-
-
-/* Forms
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea,
-select {
-  height: 38px;
-  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
-  background-color: #fff;
-  border: 1px solid #D1D1D1;
-  border-radius: 4px;
-  box-shadow: none;
-  box-sizing: border-box; }
-/* Removes awkward default styles on some inputs for iOS */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea {
-  -webkit-appearance: none;
-     -moz-appearance: none;
-          appearance: none; }
-textarea {
-  min-height: 65px;
-  padding-top: 6px;
-  padding-bottom: 6px; }
-input[type="email"]:focus,
-input[type="number"]:focus,
-input[type="search"]:focus,
-input[type="text"]:focus,
-input[type="tel"]:focus,
-input[type="url"]:focus,
-input[type="password"]:focus,
-textarea:focus,
-select:focus {
-  border: 1px solid #33C3F0;
-  outline: 0; }
-label,
-legend {
-  display: block;
-  margin-bottom: .5rem;
-  font-weight: 600; }
-fieldset {
-  padding: 0;
-  border-width: 0; }
-input[type="checkbox"],
-input[type="radio"] {
-  display: inline; }
-label > .label-body {
-  display: inline-block;
-  margin-left: .5rem;
-  font-weight: normal; }
-
-
-/* Lists
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-ul {
-  list-style: circle inside; }
-ol {
-  list-style: decimal inside; }
-ol, ul {
-  padding-left: 0;
-  margin-top: 0; }
-ul ul,
-ul ol,
-ol ol,
-ol ul {
-  margin: 1.5rem 0 1.5rem 3rem;
-  font-size: 90%; }
-li {
-  margin-bottom: 1rem; }
-
-
-/* Code
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-code {
-  padding: .2rem .5rem;
-  margin: 0 .2rem;
-  font-size: 90%;
-  white-space: nowrap;
-  background: #F1F1F1;
-  border: 1px solid #E1E1E1;
-  border-radius: 4px; }
-pre > code {
-  display: block;
-  padding: 1rem 1.5rem;
-  white-space: pre; }
-
-
-/* Tables
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-th,
-td {
-  padding: 12px 15px;
-  text-align: left;
-  border-bottom: 1px solid #E1E1E1; }
-th:first-child,
-td:first-child {
-  padding-left: 0; }
-th:last-child,
-td:last-child {
-  padding-right: 0; }
-
-
-/* Spacing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-button,
-.button {
-  margin-bottom: 1rem; }
-input,
-textarea,
-select,
-fieldset {
-  margin-bottom: 1.5rem; }
-pre,
-blockquote,
-dl,
-figure,
-table,
-p,
-ul,
-ol,
-form {
-  margin-bottom: 2.5rem; }
-
-
-/* Utilities
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.u-full-width {
-  width: 100%;
-  box-sizing: border-box; }
-.u-max-full-width {
-  max-width: 100%;
-  box-sizing: border-box; }
-.u-pull-right {
-  float: right; }
-.u-pull-left {
-  float: left; }
-
-
-/* Misc
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-hr {
-  margin-top: 3rem;
-  margin-bottom: 3.5rem;
-  border-width: 0;
-  border-top: 1px solid #E1E1E1; }
-
-
-/* Clearing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-
-/* Self Clearing Goodness */
-.container:after,
-.row:after,
-.u-cf {
-  content: "";
-  display: table;
-  clear: both; }
-
-
-/* Media Queries
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/*
-Note: The best way to structure the use of media queries is to create the queries
-near the relevant code. For example, if you wanted to change the styles for buttons
-on small devices, paste the mobile query code up in the buttons section and style it
-there.
-*/
-
-
-/* Larger than mobile */
-@media (min-width: 400px) {}
-
-/* Larger than phablet (also point when grid becomes active) */
-@media (min-width: 550px) {}
-
-/* Larger than tablet */
-@media (min-width: 750px) {}
-
-/* Larger than desktop */
-@media (min-width: 1000px) {}
-
-/* Larger than Desktop HD */
-@media (min-width: 1200px) {}

+ 11 - 53
website/src/examples/index.md

@@ -1,63 +1,21 @@
 ---
 ---
-title: Playground
+title: CDN
 type: examples
 type: examples
 order: 0
 order: 0
+snippets: [ playground/src/html/app.html, playground/src/js/app.html ]
 ---
 ---
 
 
-> Playground
+> CDN
 
 
-  <!-- Primary Page Layout
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <div class="container">
-    <div class="row">
-      <div class="twelve columns" style="margin-top: 10%">
-        <h1>
-          Loading..
-        </h1>
+<script src="/js/uppy.js"></script>
 
 
-        <h4>uppy</h4>
-        <p>
-          With this file we can easily test the built js client locally (via <code>npm run preview</code>)
-          and online.
-        </p>
-
-        <form id="upload-target" class="UppyDragDrop" method="post" action="/" enctype="multipart/form-data">
-            <svg class="UppyDragDrop-puppy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125" enable-background="new 0 0 100 100"><path d="M16.582 21.3L-.085 62.713l32.94 13.295zM99.915 62.714L66.975 76.01 83.25 21.3zM50.917 68.117L62.443 56.59H37.386l11.527 11.526v5.905l-3.063 3.32 1.474 1.36 2.59-2.807 2.59 2.807 1.475-1.358-3.063-3.32zM66.976 41.415c-3.972 0-7.193-3.22-7.193-7.193 0-3.973 3.222-7.193 7.193-7.193 3.974 0 7.193 3.22 7.193 7.192 0 3.973-3.22 7.193-7.194 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.6-1.337-1.338-1.337zM32.854 41.415c-3.973 0-7.193-3.22-7.193-7.193 0-3.973 3.22-7.193 7.194-7.193 3.973 0 7.192 3.22 7.192 7.192 0 3.973-3.22 7.193-7.192 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.598-1.337-1.337-1.337z"/></svg>          <div>
-            <input id="UppyDragDrop-input" class="UppyDragDrop-input" type="file" name="files[]" data-multiple-caption="{count} files selected" multiple />
-            <label class="UppyDragDrop-label" for="UppyDragDrop-input"><strong>Choose a file</strong><span class="UppyDragDrop-dragText"> or drag it here</span>.</label>
-            <!-- <button class="UppyDragDrop-btn" type="submit">Upload</button> -->
-          </div>
-          <div class="UppyDragDrop-status"></div>
-        </form>
-
-        <small>Puppy icon by Jorge Fernandez del Castillo Gomez <br>from the Noun Project</small>
-
-      </div>
-    </div>
-  </div>
-
-  <footer>
-    <hr />
-    <ul>
-      <li><a href="https://travis-ci.org/transloadit/uppy">Travis</a></li>
-      <li><a href="https://github.com/transloadit/uppy">GitHub</a></li>
-    </ul>
-  </footer>
-
-<!-- Include the bundled app.js client -->
-<script src="playground/static/js/app.js"></script>
-
-<!-- Apply the js client on a selector -->
 <script>
 <script>
-  // var tl = Transloadit("#upload-target");
-</script>
+var uppy = new Uppy.Core();
+uppy.use(Uppy.plugins.Tus10);
 
 
-<!-- Add the branch name to the <title> and <h1> of this page -->
-<script>
-  var branch        = location.pathname.split('/')[2] || 'local-unknown';
-  var elTitle       = document.querySelector('title');
-  var elH1          = document.querySelector('h1');
-  var title         = 'You are reviewing branch: ' + branch;
-  elTitle.innerHTML = title;
-  elH1.innerHTML    = title;
+console.log(Uppy);
+console.log('Uppy loaded from CDN with a tus 1.0 plugin');
 </script>
 </script>
+
+
+This example showcases sourcing an UMD dist build straight from a CDN.

+ 0 - 94
website/src/examples/playground/index.html

@@ -1,94 +0,0 @@
-<!DOCTYPE html>
-<html lang="en">
-<head>
-
-  <!-- Basic Page Needs
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <meta charset="utf-8">
-  <title>Loading...</title>
-  <meta name="description" content="">
-  <meta name="author" content="">
-
-  <!-- Mobile Specific Metas
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <meta name="viewport" content="width=device-width, initial-scale=1">
-
-  <!-- FONT
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <link href="//fonts.googleapis.com/css?family=Raleway:400,300,600" rel="stylesheet" type="text/css">
-
-  <!-- CSS
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <link rel="stylesheet" href="static/css/normalize.css">
-  <link rel="stylesheet" href="static/css/skeleton.css">
-
-  <!-- Favicon
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <link rel="icon" type="image/png" href="static/images/favicon.png">
-
-  <!-- Playground styles -->
-  <link rel="stylesheet" href="static/css/style.css">
-
-  <!-- Basic Uppy styles -->
-  <link rel="stylesheet" href="static/css/uppy.css">
-</head>
-<body>
-
-  <!-- Primary Page Layout
-  –––––––––––––––––––––––––––––––––––––––––––––––––– -->
-  <div class="container">
-    <div class="row">
-      <div class="twelve columns" style="margin-top: 10%">
-        <h1>
-          Loading..
-        </h1>
-
-        <h4>uppy</h4>
-        <p>
-          With this file we can easily test the built js client locally (via <code>npm run preview</code>)
-          and online.
-        </p>
-
-        <form id="upload-target" class="UppyDragDrop" method="post" action="/" enctype="multipart/form-data">
-            <svg class="UppyDragDrop-puppy" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 125" enable-background="new 0 0 100 100"><path d="M16.582 21.3L-.085 62.713l32.94 13.295zM99.915 62.714L66.975 76.01 83.25 21.3zM50.917 68.117L62.443 56.59H37.386l11.527 11.526v5.905l-3.063 3.32 1.474 1.36 2.59-2.807 2.59 2.807 1.475-1.358-3.063-3.32zM66.976 41.415c-3.972 0-7.193-3.22-7.193-7.193 0-3.973 3.222-7.193 7.193-7.193 3.974 0 7.193 3.22 7.193 7.192 0 3.973-3.22 7.193-7.194 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.6-1.337-1.338-1.337zM32.854 41.415c-3.973 0-7.193-3.22-7.193-7.193 0-3.973 3.22-7.193 7.194-7.193 3.973 0 7.192 3.22 7.192 7.192 0 3.973-3.22 7.193-7.192 7.193m2.506-11.732c-.738 0-1.337.6-1.337 1.337s.6 1.336 1.337 1.336 1.337-.598 1.337-1.336-.598-1.337-1.337-1.337z"/></svg>          <div>
-            <input id="UppyDragDrop-input" class="UppyDragDrop-input" type="file" name="files[]" data-multiple-caption="{count} files selected" multiple />
-            <label class="UppyDragDrop-label" for="UppyDragDrop-input"><strong>Choose a file</strong><span class="UppyDragDrop-dragText"> or drag it here</span>.</label>
-            <!-- <button class="UppyDragDrop-btn" type="submit">Upload</button> -->
-          </div>
-          <div class="UppyDragDrop-status"></div>
-        </form>
-
-        <small>Puppy icon by Jorge Fernandez del Castillo Gomez <br>from the Noun Project</small>
-
-      </div>
-    </div>
-  </div>
-
-  <footer>
-    <hr />
-    <ul>
-      <li><a href="https://travis-ci.org/transloadit/uppy">Travis</a></li>
-      <li><a href="https://github.com/transloadit/uppy">GitHub</a></li>
-    </ul>
-  </footer>
-
-</body>
-
-<!-- Include the bundled app.js client -->
-<script src="static/js/app.js"></script>
-
-<!-- Apply the js client on a selector -->
-<script>
-  // var tl = Transloadit("#upload-target");
-</script>
-
-<!-- Add the branch name to the <title> and <h1> of this page -->
-<script>
-  var branch        = location.pathname.split('/')[2] || 'local-unknown';
-  var elTitle       = document.querySelector('title');
-  var elH1          = document.querySelector('h1');
-  var title         = 'You are reviewing branch: ' + branch;
-  elTitle.innerHTML = title;
-  elH1.innerHTML    = title;
-</script>
-</html>

+ 0 - 13
website/src/examples/playground/package.json

@@ -1,13 +0,0 @@
-{
-  "name": "playground",
-  "version": "1.0.0",
-  "description": "",
-  "main": "index.js",
-  "scripts": {
-    "build": "../../node_modules/.bin/browserify src/js/app.js -o static/js/app.js -t [ babelify ]",
-    "watch": "../../node_modules/.bin/watchify src/js/app.js -o static/js/app.js",
-    "test": "echo \"Error: no test specified\" && exit 1"
-  },
-  "author": "",
-  "license": "ISC"
-}

+ 1 - 8
website/src/examples/playground/src/js/app.js

@@ -1,8 +1 @@
-// import Uppy from 'uppy/core';
-// import { DragDrop, Tus10 } from 'uppy/plugins';
-
-// const uppy = new Uppy({wait: false});
-// const files = uppy
-//   .use(DragDrop, {selector: '#upload-target'})
-//   .use(Tus10, {endpoint: 'http://master.tus.io:8080'})
-//   .run();
+// empty

+ 0 - 0
website/src/examples/playground/static/css/.empty


+ 0 - 427
website/src/examples/playground/static/css/normalize.css

@@ -1,427 +0,0 @@
-/*! normalize.css v3.0.2 | MIT License | git.io/normalize */
-
-/**
- * 1. Set default font family to sans-serif.
- * 2. Prevent iOS text size adjust after orientation change, without disabling
- *    user zoom.
- */
-
-html {
-  font-family: sans-serif; /* 1 */
-  -ms-text-size-adjust: 100%; /* 2 */
-  -webkit-text-size-adjust: 100%; /* 2 */
-}
-
-/**
- * Remove default margin.
- */
-
-body {
-  margin: 0;
-}
-
-/* HTML5 display definitions
-   ========================================================================== */
-
-/**
- * Correct `block` display not defined for any HTML5 element in IE 8/9.
- * Correct `block` display not defined for `details` or `summary` in IE 10/11
- * and Firefox.
- * Correct `block` display not defined for `main` in IE 11.
- */
-
-article,
-aside,
-details,
-figcaption,
-figure,
-footer,
-header,
-hgroup,
-main,
-menu,
-nav,
-section,
-summary {
-  display: block;
-}
-
-/**
- * 1. Correct `inline-block` display not defined in IE 8/9.
- * 2. Normalize vertical alignment of `progress` in Chrome, Firefox, and Opera.
- */
-
-audio,
-canvas,
-progress,
-video {
-  display: inline-block; /* 1 */
-  vertical-align: baseline; /* 2 */
-}
-
-/**
- * Prevent modern browsers from displaying `audio` without controls.
- * Remove excess height in iOS 5 devices.
- */
-
-audio:not([controls]) {
-  display: none;
-  height: 0;
-}
-
-/**
- * Address `[hidden]` styling not present in IE 8/9/10.
- * Hide the `template` element in IE 8/9/11, Safari, and Firefox < 22.
- */
-
-[hidden],
-template {
-  display: none;
-}
-
-/* Links
-   ========================================================================== */
-
-/**
- * Remove the gray background color from active links in IE 10.
- */
-
-a {
-  background-color: transparent;
-}
-
-/**
- * Improve readability when focused and also mouse hovered in all browsers.
- */
-
-a:active,
-a:hover {
-  outline: 0;
-}
-
-/* Text-level semantics
-   ========================================================================== */
-
-/**
- * Address styling not present in IE 8/9/10/11, Safari, and Chrome.
- */
-
-abbr[title] {
-  border-bottom: 1px dotted;
-}
-
-/**
- * Address style set to `bolder` in Firefox 4+, Safari, and Chrome.
- */
-
-b,
-strong {
-  font-weight: bold;
-}
-
-/**
- * Address styling not present in Safari and Chrome.
- */
-
-dfn {
-  font-style: italic;
-}
-
-/**
- * Address variable `h1` font-size and margin within `section` and `article`
- * contexts in Firefox 4+, Safari, and Chrome.
- */
-
-h1 {
-  font-size: 2em;
-  margin: 0.67em 0;
-}
-
-/**
- * Address styling not present in IE 8/9.
- */
-
-mark {
-  background: #ff0;
-  color: #000;
-}
-
-/**
- * Address inconsistent and variable font size in all browsers.
- */
-
-small {
-  font-size: 80%;
-}
-
-/**
- * Prevent `sub` and `sup` affecting `line-height` in all browsers.
- */
-
-sub,
-sup {
-  font-size: 75%;
-  line-height: 0;
-  position: relative;
-  vertical-align: baseline;
-}
-
-sup {
-  top: -0.5em;
-}
-
-sub {
-  bottom: -0.25em;
-}
-
-/* Embedded content
-   ========================================================================== */
-
-/**
- * Remove border when inside `a` element in IE 8/9/10.
- */
-
-img {
-  border: 0;
-}
-
-/**
- * Correct overflow not hidden in IE 9/10/11.
- */
-
-svg:not(:root) {
-  overflow: hidden;
-}
-
-/* Grouping content
-   ========================================================================== */
-
-/**
- * Address margin not present in IE 8/9 and Safari.
- */
-
-figure {
-  margin: 1em 40px;
-}
-
-/**
- * Address differences between Firefox and other browsers.
- */
-
-hr {
-  -moz-box-sizing: content-box;
-  box-sizing: content-box;
-  height: 0;
-}
-
-/**
- * Contain overflow in all browsers.
- */
-
-pre {
-  overflow: auto;
-}
-
-/**
- * Address odd `em`-unit font size rendering in all browsers.
- */
-
-code,
-kbd,
-pre,
-samp {
-  font-family: monospace, monospace;
-  font-size: 1em;
-}
-
-/* Forms
-   ========================================================================== */
-
-/**
- * Known limitation: by default, Chrome and Safari on OS X allow very limited
- * styling of `select`, unless a `border` property is set.
- */
-
-/**
- * 1. Correct color not being inherited.
- *    Known issue: affects color of disabled elements.
- * 2. Correct font properties not being inherited.
- * 3. Address margins set differently in Firefox 4+, Safari, and Chrome.
- */
-
-button,
-input,
-optgroup,
-select,
-textarea {
-  color: inherit; /* 1 */
-  font: inherit; /* 2 */
-  margin: 0; /* 3 */
-}
-
-/**
- * Address `overflow` set to `hidden` in IE 8/9/10/11.
- */
-
-button {
-  overflow: visible;
-}
-
-/**
- * Address inconsistent `text-transform` inheritance for `button` and `select`.
- * All other form control elements do not inherit `text-transform` values.
- * Correct `button` style inheritance in Firefox, IE 8/9/10/11, and Opera.
- * Correct `select` style inheritance in Firefox.
- */
-
-button,
-select {
-  text-transform: none;
-}
-
-/**
- * 1. Avoid the WebKit bug in Android 4.0.* where (2) destroys native `audio`
- *    and `video` controls.
- * 2. Correct inability to style clickable `input` types in iOS.
- * 3. Improve usability and consistency of cursor style between image-type
- *    `input` and others.
- */
-
-button,
-html input[type="button"], /* 1 */
-input[type="reset"],
-input[type="submit"] {
-  -webkit-appearance: button; /* 2 */
-  cursor: pointer; /* 3 */
-}
-
-/**
- * Re-set default cursor for disabled elements.
- */
-
-button[disabled],
-html input[disabled] {
-  cursor: default;
-}
-
-/**
- * Remove inner padding and border in Firefox 4+.
- */
-
-button::-moz-focus-inner,
-input::-moz-focus-inner {
-  border: 0;
-  padding: 0;
-}
-
-/**
- * Address Firefox 4+ setting `line-height` on `input` using `!important` in
- * the UA stylesheet.
- */
-
-input {
-  line-height: normal;
-}
-
-/**
- * It's recommended that you don't attempt to style these elements.
- * Firefox's implementation doesn't respect box-sizing, padding, or width.
- *
- * 1. Address box sizing set to `content-box` in IE 8/9/10.
- * 2. Remove excess padding in IE 8/9/10.
- */
-
-input[type="checkbox"],
-input[type="radio"] {
-  box-sizing: border-box; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Fix the cursor style for Chrome's increment/decrement buttons. For certain
- * `font-size` values of the `input`, it causes the cursor style of the
- * decrement button to change from `default` to `text`.
- */
-
-input[type="number"]::-webkit-inner-spin-button,
-input[type="number"]::-webkit-outer-spin-button {
-  height: auto;
-}
-
-/**
- * 1. Address `appearance` set to `searchfield` in Safari and Chrome.
- * 2. Address `box-sizing` set to `border-box` in Safari and Chrome
- *    (include `-moz` to future-proof).
- */
-
-input[type="search"] {
-  -webkit-appearance: textfield; /* 1 */
-  -moz-box-sizing: content-box;
-  -webkit-box-sizing: content-box; /* 2 */
-  box-sizing: content-box;
-}
-
-/**
- * Remove inner padding and search cancel button in Safari and Chrome on OS X.
- * Safari (but not Chrome) clips the cancel button when the search input has
- * padding (and `textfield` appearance).
- */
-
-input[type="search"]::-webkit-search-cancel-button,
-input[type="search"]::-webkit-search-decoration {
-  -webkit-appearance: none;
-}
-
-/**
- * Define consistent border, margin, and padding.
- */
-
-fieldset {
-  border: 1px solid #c0c0c0;
-  margin: 0 2px;
-  padding: 0.35em 0.625em 0.75em;
-}
-
-/**
- * 1. Correct `color` not being inherited in IE 8/9/10/11.
- * 2. Remove padding so people aren't caught out if they zero out fieldsets.
- */
-
-legend {
-  border: 0; /* 1 */
-  padding: 0; /* 2 */
-}
-
-/**
- * Remove default vertical scrollbar in IE 8/9/10/11.
- */
-
-textarea {
-  overflow: auto;
-}
-
-/**
- * Don't inherit the `font-weight` (applied by a rule above).
- * NOTE: the default cannot safely be changed in Chrome and Safari on OS X.
- */
-
-optgroup {
-  font-weight: bold;
-}
-
-/* Tables
-   ========================================================================== */
-
-/**
- * Remove most spacing between table cells.
- */
-
-table {
-  border-collapse: collapse;
-  border-spacing: 0;
-}
-
-td,
-th {
-  padding: 0;
-}

+ 0 - 418
website/src/examples/playground/static/css/skeleton.css

@@ -1,418 +0,0 @@
-/*
-* Skeleton V2.0.4
-* Copyright 2014, Dave Gamache
-* www.getskeleton.com
-* Free to use under the MIT license.
-* http://www.opensource.org/licenses/mit-license.php
-* 12/29/2014
-*/
-
-
-/* Table of contents
-––––––––––––––––––––––––––––––––––––––––––––––––––
-- Grid
-- Base Styles
-- Typography
-- Links
-- Buttons
-- Forms
-- Lists
-- Code
-- Tables
-- Spacing
-- Utilities
-- Clearing
-- Media Queries
-*/
-
-
-/* Grid
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.container {
-  position: relative;
-  width: 100%;
-  max-width: 960px;
-  margin: 0 auto;
-  padding: 0 20px;
-  box-sizing: border-box; }
-.column,
-.columns {
-  width: 100%;
-  float: left;
-  box-sizing: border-box; }
-
-/* For devices larger than 400px */
-@media (min-width: 400px) {
-  .container {
-    width: 85%;
-    padding: 0; }
-}
-
-/* For devices larger than 550px */
-@media (min-width: 550px) {
-  .container {
-    width: 80%; }
-  .column,
-  .columns {
-    margin-left: 4%; }
-  .column:first-child,
-  .columns:first-child {
-    margin-left: 0; }
-
-  .one.column,
-  .one.columns                    { width: 4.66666666667%; }
-  .two.columns                    { width: 13.3333333333%; }
-  .three.columns                  { width: 22%;            }
-  .four.columns                   { width: 30.6666666667%; }
-  .five.columns                   { width: 39.3333333333%; }
-  .six.columns                    { width: 48%;            }
-  .seven.columns                  { width: 56.6666666667%; }
-  .eight.columns                  { width: 65.3333333333%; }
-  .nine.columns                   { width: 74.0%;          }
-  .ten.columns                    { width: 82.6666666667%; }
-  .eleven.columns                 { width: 91.3333333333%; }
-  .twelve.columns                 { width: 100%; margin-left: 0; }
-
-  .one-third.column               { width: 30.6666666667%; }
-  .two-thirds.column              { width: 65.3333333333%; }
-
-  .one-half.column                { width: 48%; }
-
-  /* Offsets */
-  .offset-by-one.column,
-  .offset-by-one.columns          { margin-left: 8.66666666667%; }
-  .offset-by-two.column,
-  .offset-by-two.columns          { margin-left: 17.3333333333%; }
-  .offset-by-three.column,
-  .offset-by-three.columns        { margin-left: 26%;            }
-  .offset-by-four.column,
-  .offset-by-four.columns         { margin-left: 34.6666666667%; }
-  .offset-by-five.column,
-  .offset-by-five.columns         { margin-left: 43.3333333333%; }
-  .offset-by-six.column,
-  .offset-by-six.columns          { margin-left: 52%;            }
-  .offset-by-seven.column,
-  .offset-by-seven.columns        { margin-left: 60.6666666667%; }
-  .offset-by-eight.column,
-  .offset-by-eight.columns        { margin-left: 69.3333333333%; }
-  .offset-by-nine.column,
-  .offset-by-nine.columns         { margin-left: 78.0%;          }
-  .offset-by-ten.column,
-  .offset-by-ten.columns          { margin-left: 86.6666666667%; }
-  .offset-by-eleven.column,
-  .offset-by-eleven.columns       { margin-left: 95.3333333333%; }
-
-  .offset-by-one-third.column,
-  .offset-by-one-third.columns    { margin-left: 34.6666666667%; }
-  .offset-by-two-thirds.column,
-  .offset-by-two-thirds.columns   { margin-left: 69.3333333333%; }
-
-  .offset-by-one-half.column,
-  .offset-by-one-half.columns     { margin-left: 52%; }
-
-}
-
-
-/* Base Styles
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/* NOTE
-html is set to 62.5% so that all the REM measurements throughout Skeleton
-are based on 10px sizing. So basically 1.5rem = 15px :) */
-html {
-  font-size: 62.5%; }
-body {
-  font-size: 1.5em; /* currently ems cause chrome bug misinterpreting rems on body element */
-  line-height: 1.6;
-  font-weight: 400;
-  font-family: "Raleway", "HelveticaNeue", "Helvetica Neue", Helvetica, Arial, sans-serif;
-  color: #222; }
-
-
-/* Typography
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-h1, h2, h3, h4, h5, h6 {
-  margin-top: 0;
-  margin-bottom: 2rem;
-  font-weight: 300; }
-h1 { font-size: 4.0rem; line-height: 1.2;  letter-spacing: -.1rem;}
-h2 { font-size: 3.6rem; line-height: 1.25; letter-spacing: -.1rem; }
-h3 { font-size: 3.0rem; line-height: 1.3;  letter-spacing: -.1rem; }
-h4 { font-size: 2.4rem; line-height: 1.35; letter-spacing: -.08rem; }
-h5 { font-size: 1.8rem; line-height: 1.5;  letter-spacing: -.05rem; }
-h6 { font-size: 1.5rem; line-height: 1.6;  letter-spacing: 0; }
-
-/* Larger than phablet */
-@media (min-width: 550px) {
-  h1 { font-size: 5.0rem; }
-  h2 { font-size: 4.2rem; }
-  h3 { font-size: 3.6rem; }
-  h4 { font-size: 3.0rem; }
-  h5 { font-size: 2.4rem; }
-  h6 { font-size: 1.5rem; }
-}
-
-p {
-  margin-top: 0; }
-
-
-/* Links
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-a {
-  color: #1EAEDB; }
-a:hover {
-  color: #0FA0CE; }
-
-
-/* Buttons
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.button,
-button,
-input[type="submit"],
-input[type="reset"],
-input[type="button"] {
-  display: inline-block;
-  height: 38px;
-  padding: 0 30px;
-  color: #555;
-  text-align: center;
-  font-size: 11px;
-  font-weight: 600;
-  line-height: 38px;
-  letter-spacing: .1rem;
-  text-transform: uppercase;
-  text-decoration: none;
-  white-space: nowrap;
-  background-color: transparent;
-  border-radius: 4px;
-  border: 1px solid #bbb;
-  cursor: pointer;
-  box-sizing: border-box; }
-.button:hover,
-button:hover,
-input[type="submit"]:hover,
-input[type="reset"]:hover,
-input[type="button"]:hover,
-.button:focus,
-button:focus,
-input[type="submit"]:focus,
-input[type="reset"]:focus,
-input[type="button"]:focus {
-  color: #333;
-  border-color: #888;
-  outline: 0; }
-.button.button-primary,
-button.button-primary,
-input[type="submit"].button-primary,
-input[type="reset"].button-primary,
-input[type="button"].button-primary {
-  color: #FFF;
-  background-color: #33C3F0;
-  border-color: #33C3F0; }
-.button.button-primary:hover,
-button.button-primary:hover,
-input[type="submit"].button-primary:hover,
-input[type="reset"].button-primary:hover,
-input[type="button"].button-primary:hover,
-.button.button-primary:focus,
-button.button-primary:focus,
-input[type="submit"].button-primary:focus,
-input[type="reset"].button-primary:focus,
-input[type="button"].button-primary:focus {
-  color: #FFF;
-  background-color: #1EAEDB;
-  border-color: #1EAEDB; }
-
-
-/* Forms
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea,
-select {
-  height: 38px;
-  padding: 6px 10px; /* The 6px vertically centers text on FF, ignored by Webkit */
-  background-color: #fff;
-  border: 1px solid #D1D1D1;
-  border-radius: 4px;
-  box-shadow: none;
-  box-sizing: border-box; }
-/* Removes awkward default styles on some inputs for iOS */
-input[type="email"],
-input[type="number"],
-input[type="search"],
-input[type="text"],
-input[type="tel"],
-input[type="url"],
-input[type="password"],
-textarea {
-  -webkit-appearance: none;
-     -moz-appearance: none;
-          appearance: none; }
-textarea {
-  min-height: 65px;
-  padding-top: 6px;
-  padding-bottom: 6px; }
-input[type="email"]:focus,
-input[type="number"]:focus,
-input[type="search"]:focus,
-input[type="text"]:focus,
-input[type="tel"]:focus,
-input[type="url"]:focus,
-input[type="password"]:focus,
-textarea:focus,
-select:focus {
-  border: 1px solid #33C3F0;
-  outline: 0; }
-label,
-legend {
-  display: block;
-  margin-bottom: .5rem;
-  font-weight: 600; }
-fieldset {
-  padding: 0;
-  border-width: 0; }
-input[type="checkbox"],
-input[type="radio"] {
-  display: inline; }
-label > .label-body {
-  display: inline-block;
-  margin-left: .5rem;
-  font-weight: normal; }
-
-
-/* Lists
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-ul {
-  list-style: circle inside; }
-ol {
-  list-style: decimal inside; }
-ol, ul {
-  padding-left: 0;
-  margin-top: 0; }
-ul ul,
-ul ol,
-ol ol,
-ol ul {
-  margin: 1.5rem 0 1.5rem 3rem;
-  font-size: 90%; }
-li {
-  margin-bottom: 1rem; }
-
-
-/* Code
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-code {
-  padding: .2rem .5rem;
-  margin: 0 .2rem;
-  font-size: 90%;
-  white-space: nowrap;
-  background: #F1F1F1;
-  border: 1px solid #E1E1E1;
-  border-radius: 4px; }
-pre > code {
-  display: block;
-  padding: 1rem 1.5rem;
-  white-space: pre; }
-
-
-/* Tables
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-th,
-td {
-  padding: 12px 15px;
-  text-align: left;
-  border-bottom: 1px solid #E1E1E1; }
-th:first-child,
-td:first-child {
-  padding-left: 0; }
-th:last-child,
-td:last-child {
-  padding-right: 0; }
-
-
-/* Spacing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-button,
-.button {
-  margin-bottom: 1rem; }
-input,
-textarea,
-select,
-fieldset {
-  margin-bottom: 1.5rem; }
-pre,
-blockquote,
-dl,
-figure,
-table,
-p,
-ul,
-ol,
-form {
-  margin-bottom: 2.5rem; }
-
-
-/* Utilities
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-.u-full-width {
-  width: 100%;
-  box-sizing: border-box; }
-.u-max-full-width {
-  max-width: 100%;
-  box-sizing: border-box; }
-.u-pull-right {
-  float: right; }
-.u-pull-left {
-  float: left; }
-
-
-/* Misc
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-hr {
-  margin-top: 3rem;
-  margin-bottom: 3.5rem;
-  border-width: 0;
-  border-top: 1px solid #E1E1E1; }
-
-
-/* Clearing
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-
-/* Self Clearing Goodness */
-.container:after,
-.row:after,
-.u-cf {
-  content: "";
-  display: table;
-  clear: both; }
-
-
-/* Media Queries
-–––––––––––––––––––––––––––––––––––––––––––––––––– */
-/*
-Note: The best way to structure the use of media queries is to create the queries
-near the relevant code. For example, if you wanted to change the styles for buttons
-on small devices, paste the mobile query code up in the buttons section and style it
-there.
-*/
-
-
-/* Larger than mobile */
-@media (min-width: 400px) {}
-
-/* Larger than phablet (also point when grid becomes active) */
-@media (min-width: 550px) {}
-
-/* Larger than tablet */
-@media (min-width: 750px) {}
-
-/* Larger than desktop */
-@media (min-width: 1000px) {}
-
-/* Larger than Desktop HD */
-@media (min-width: 1200px) {}

+ 0 - 3
website/src/examples/playground/static/css/style.css

@@ -1,3 +0,0 @@
-.UppyDragDrop-puppy {
-  max-width: 80px;
-}

+ 0 - 48
website/src/examples/playground/static/css/uppy.css

@@ -1,48 +0,0 @@
-.uppy {
-  font-family: "Comic Sans MS";
-  color: purple;
-  border: 1px dashed pink;
-  font-size: 32px;
-}
-
-/**
-* Drag & Drop
-*/
-
-.UppyDragDrop {
-  width: 300px;
-  text-align: center;
-  padding: 100px 10px;
-}
-
-/* http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/ */
-.UppyDragDrop-input {
-  width: 0.1px;
-	height: 0.1px;
-	opacity: 0;
-	overflow: hidden;
-	position: absolute;
-	z-index: -1;
-}
-
-.UppyDragDrop.is-dragdrop-supported {
-  border: 2px dashed;
-  border-color: #ccc;
-}
-
-.UppyDragDrop-label {
-  cursor: pointer;
-}
-
-.UppyDragDrop-dragText {
-  display: none;
-}
-
-.is-dragdrop-supported .UppyDragDrop-dragText {
-  display: inline;
-}
-
-.UppyDragDrop.is-dragover {
-  border-color: #d2ecea;
-  background-color: #dbf5f3;
-}

+ 0 - 2097
website/src/examples/uppy.js

@@ -1,2097 +0,0 @@
-(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Uppy = f()}})(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){
-/**
- * Module dependencies.
- */
-
-var Emitter = require('emitter');
-var reduce = require('reduce');
-
-/**
- * Root reference for iframes.
- */
-
-var root;
-if (typeof window !== 'undefined') { // Browser window
-  root = window;
-} else if (typeof self !== 'undefined') { // Web Worker
-  root = self;
-} else { // Other environments
-  root = this;
-}
-
-/**
- * Noop.
- */
-
-function noop(){};
-
-/**
- * Check if `obj` is a host object,
- * we don't want to serialize these :)
- *
- * TODO: future proof, move to compoent land
- *
- * @param {Object} obj
- * @return {Boolean}
- * @api private
- */
-
-function isHost(obj) {
-  var str = {}.toString.call(obj);
-
-  switch (str) {
-    case '[object File]':
-    case '[object Blob]':
-    case '[object FormData]':
-      return true;
-    default:
-      return false;
-  }
-}
-
-/**
- * Determine XHR.
- */
-
-request.getXHR = function () {
-  if (root.XMLHttpRequest
-      && (!root.location || 'file:' != root.location.protocol
-          || !root.ActiveXObject)) {
-    return new XMLHttpRequest;
-  } else {
-    try { return new ActiveXObject('Microsoft.XMLHTTP'); } catch(e) {}
-    try { return new ActiveXObject('Msxml2.XMLHTTP.6.0'); } catch(e) {}
-    try { return new ActiveXObject('Msxml2.XMLHTTP.3.0'); } catch(e) {}
-    try { return new ActiveXObject('Msxml2.XMLHTTP'); } catch(e) {}
-  }
-  return false;
-};
-
-/**
- * Removes leading and trailing whitespace, added to support IE.
- *
- * @param {String} s
- * @return {String}
- * @api private
- */
-
-var trim = ''.trim
-  ? function(s) { return s.trim(); }
-  : function(s) { return s.replace(/(^\s*|\s*$)/g, ''); };
-
-/**
- * Check if `obj` is an object.
- *
- * @param {Object} obj
- * @return {Boolean}
- * @api private
- */
-
-function isObject(obj) {
-  return obj === Object(obj);
-}
-
-/**
- * Serialize the given `obj`.
- *
- * @param {Object} obj
- * @return {String}
- * @api private
- */
-
-function serialize(obj) {
-  if (!isObject(obj)) return obj;
-  var pairs = [];
-  for (var key in obj) {
-    if (null != obj[key]) {
-      pushEncodedKeyValuePair(pairs, key, obj[key]);
-        }
-      }
-  return pairs.join('&');
-}
-
-/**
- * Helps 'serialize' with serializing arrays.
- * Mutates the pairs array.
- *
- * @param {Array} pairs
- * @param {String} key
- * @param {Mixed} val
- */
-
-function pushEncodedKeyValuePair(pairs, key, val) {
-  if (Array.isArray(val)) {
-    return val.forEach(function(v) {
-      pushEncodedKeyValuePair(pairs, key, v);
-    });
-  }
-  pairs.push(encodeURIComponent(key)
-    + '=' + encodeURIComponent(val));
-}
-
-/**
- * Expose serialization method.
- */
-
- request.serializeObject = serialize;
-
- /**
-  * Parse the given x-www-form-urlencoded `str`.
-  *
-  * @param {String} str
-  * @return {Object}
-  * @api private
-  */
-
-function parseString(str) {
-  var obj = {};
-  var pairs = str.split('&');
-  var parts;
-  var pair;
-
-  for (var i = 0, len = pairs.length; i < len; ++i) {
-    pair = pairs[i];
-    parts = pair.split('=');
-    obj[decodeURIComponent(parts[0])] = decodeURIComponent(parts[1]);
-  }
-
-  return obj;
-}
-
-/**
- * Expose parser.
- */
-
-request.parseString = parseString;
-
-/**
- * Default MIME type map.
- *
- *     superagent.types.xml = 'application/xml';
- *
- */
-
-request.types = {
-  html: 'text/html',
-  json: 'application/json',
-  xml: 'application/xml',
-  urlencoded: 'application/x-www-form-urlencoded',
-  'form': 'application/x-www-form-urlencoded',
-  'form-data': 'application/x-www-form-urlencoded'
-};
-
-/**
- * Default serialization map.
- *
- *     superagent.serialize['application/xml'] = function(obj){
- *       return 'generated xml here';
- *     };
- *
- */
-
- request.serialize = {
-   'application/x-www-form-urlencoded': serialize,
-   'application/json': JSON.stringify
- };
-
- /**
-  * Default parsers.
-  *
-  *     superagent.parse['application/xml'] = function(str){
-  *       return { object parsed from str };
-  *     };
-  *
-  */
-
-request.parse = {
-  'application/x-www-form-urlencoded': parseString,
-  'application/json': JSON.parse
-};
-
-/**
- * Parse the given header `str` into
- * an object containing the mapped fields.
- *
- * @param {String} str
- * @return {Object}
- * @api private
- */
-
-function parseHeader(str) {
-  var lines = str.split(/\r?\n/);
-  var fields = {};
-  var index;
-  var line;
-  var field;
-  var val;
-
-  lines.pop(); // trailing CRLF
-
-  for (var i = 0, len = lines.length; i < len; ++i) {
-    line = lines[i];
-    index = line.indexOf(':');
-    field = line.slice(0, index).toLowerCase();
-    val = trim(line.slice(index + 1));
-    fields[field] = val;
-  }
-
-  return fields;
-}
-
-/**
- * Return the mime type for the given `str`.
- *
- * @param {String} str
- * @return {String}
- * @api private
- */
-
-function type(str){
-  return str.split(/ *; */).shift();
-};
-
-/**
- * Return header field parameters.
- *
- * @param {String} str
- * @return {Object}
- * @api private
- */
-
-function params(str){
-  return reduce(str.split(/ *; */), function(obj, str){
-    var parts = str.split(/ *= */)
-      , key = parts.shift()
-      , val = parts.shift();
-
-    if (key && val) obj[key] = val;
-    return obj;
-  }, {});
-};
-
-/**
- * Initialize a new `Response` with the given `xhr`.
- *
- *  - set flags (.ok, .error, etc)
- *  - parse header
- *
- * Examples:
- *
- *  Aliasing `superagent` as `request` is nice:
- *
- *      request = superagent;
- *
- *  We can use the promise-like API, or pass callbacks:
- *
- *      request.get('/').end(function(res){});
- *      request.get('/', function(res){});
- *
- *  Sending data can be chained:
- *
- *      request
- *        .post('/user')
- *        .send({ name: 'tj' })
- *        .end(function(res){});
- *
- *  Or passed to `.send()`:
- *
- *      request
- *        .post('/user')
- *        .send({ name: 'tj' }, function(res){});
- *
- *  Or passed to `.post()`:
- *
- *      request
- *        .post('/user', { name: 'tj' })
- *        .end(function(res){});
- *
- * Or further reduced to a single call for simple cases:
- *
- *      request
- *        .post('/user', { name: 'tj' }, function(res){});
- *
- * @param {XMLHTTPRequest} xhr
- * @param {Object} options
- * @api private
- */
-
-function Response(req, options) {
-  options = options || {};
-  this.req = req;
-  this.xhr = this.req.xhr;
-  // responseText is accessible only if responseType is '' or 'text' and on older browsers
-  this.text = ((this.req.method !='HEAD' && (this.xhr.responseType === '' || this.xhr.responseType === 'text')) || typeof this.xhr.responseType === 'undefined')
-     ? this.xhr.responseText
-     : null;
-  this.statusText = this.req.xhr.statusText;
-  this.setStatusProperties(this.xhr.status);
-  this.header = this.headers = parseHeader(this.xhr.getAllResponseHeaders());
-  // getAllResponseHeaders sometimes falsely returns "" for CORS requests, but
-  // getResponseHeader still works. so we get content-type even if getting
-  // other headers fails.
-  this.header['content-type'] = this.xhr.getResponseHeader('content-type');
-  this.setHeaderProperties(this.header);
-  this.body = this.req.method != 'HEAD'
-    ? this.parseBody(this.text ? this.text : this.xhr.response)
-    : null;
-}
-
-/**
- * Get case-insensitive `field` value.
- *
- * @param {String} field
- * @return {String}
- * @api public
- */
-
-Response.prototype.get = function(field){
-  return this.header[field.toLowerCase()];
-};
-
-/**
- * Set header related properties:
- *
- *   - `.type` the content type without params
- *
- * A response of "Content-Type: text/plain; charset=utf-8"
- * will provide you with a `.type` of "text/plain".
- *
- * @param {Object} header
- * @api private
- */
-
-Response.prototype.setHeaderProperties = function(header){
-  // content-type
-  var ct = this.header['content-type'] || '';
-  this.type = type(ct);
-
-  // params
-  var obj = params(ct);
-  for (var key in obj) this[key] = obj[key];
-};
-
-/**
- * Parse the given body `str`.
- *
- * Used for auto-parsing of bodies. Parsers
- * are defined on the `superagent.parse` object.
- *
- * @param {String} str
- * @return {Mixed}
- * @api private
- */
-
-Response.prototype.parseBody = function(str){
-  var parse = request.parse[this.type];
-  return parse && str && (str.length || str instanceof Object)
-    ? parse(str)
-    : null;
-};
-
-/**
- * Set flags such as `.ok` based on `status`.
- *
- * For example a 2xx response will give you a `.ok` of __true__
- * whereas 5xx will be __false__ and `.error` will be __true__. The
- * `.clientError` and `.serverError` are also available to be more
- * specific, and `.statusType` is the class of error ranging from 1..5
- * sometimes useful for mapping respond colors etc.
- *
- * "sugar" properties are also defined for common cases. Currently providing:
- *
- *   - .noContent
- *   - .badRequest
- *   - .unauthorized
- *   - .notAcceptable
- *   - .notFound
- *
- * @param {Number} status
- * @api private
- */
-
-Response.prototype.setStatusProperties = function(status){
-  // handle IE9 bug: http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request
-  if (status === 1223) {
-    status = 204;
-  }
-
-  var type = status / 100 | 0;
-
-  // status / class
-  this.status = this.statusCode = status;
-  this.statusType = type;
-
-  // basics
-  this.info = 1 == type;
-  this.ok = 2 == type;
-  this.clientError = 4 == type;
-  this.serverError = 5 == type;
-  this.error = (4 == type || 5 == type)
-    ? this.toError()
-    : false;
-
-  // sugar
-  this.accepted = 202 == status;
-  this.noContent = 204 == status;
-  this.badRequest = 400 == status;
-  this.unauthorized = 401 == status;
-  this.notAcceptable = 406 == status;
-  this.notFound = 404 == status;
-  this.forbidden = 403 == status;
-};
-
-/**
- * Return an `Error` representative of this response.
- *
- * @return {Error}
- * @api public
- */
-
-Response.prototype.toError = function(){
-  var req = this.req;
-  var method = req.method;
-  var url = req.url;
-
-  var msg = 'cannot ' + method + ' ' + url + ' (' + this.status + ')';
-  var err = new Error(msg);
-  err.status = this.status;
-  err.method = method;
-  err.url = url;
-
-  return err;
-};
-
-/**
- * Expose `Response`.
- */
-
-request.Response = Response;
-
-/**
- * Initialize a new `Request` with the given `method` and `url`.
- *
- * @param {String} method
- * @param {String} url
- * @api public
- */
-
-function Request(method, url) {
-  var self = this;
-  Emitter.call(this);
-  this._query = this._query || [];
-  this.method = method;
-  this.url = url;
-  this.header = {};
-  this._header = {};
-  this.on('end', function(){
-    var err = null;
-    var res = null;
-
-    try {
-      res = new Response(self);
-    } catch(e) {
-      err = new Error('Parser is unable to parse the response');
-      err.parse = true;
-      err.original = e;
-      return self.callback(err);
-    }
-
-    self.emit('response', res);
-
-    if (err) {
-      return self.callback(err, res);
-    }
-
-    if (res.status >= 200 && res.status < 300) {
-      return self.callback(err, res);
-    }
-
-    var new_err = new Error(res.statusText || 'Unsuccessful HTTP response');
-    new_err.original = err;
-    new_err.response = res;
-    new_err.status = res.status;
-
-    self.callback(new_err, res);
-  });
-}
-
-/**
- * Mixin `Emitter`.
- */
-
-Emitter(Request.prototype);
-
-/**
- * Allow for extension
- */
-
-Request.prototype.use = function(fn) {
-  fn(this);
-  return this;
-}
-
-/**
- * Set timeout to `ms`.
- *
- * @param {Number} ms
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.timeout = function(ms){
-  this._timeout = ms;
-  return this;
-};
-
-/**
- * Clear previous timeout.
- *
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.clearTimeout = function(){
-  this._timeout = 0;
-  clearTimeout(this._timer);
-  return this;
-};
-
-/**
- * Abort the request, and clear potential timeout.
- *
- * @return {Request}
- * @api public
- */
-
-Request.prototype.abort = function(){
-  if (this.aborted) return;
-  this.aborted = true;
-  this.xhr.abort();
-  this.clearTimeout();
-  this.emit('abort');
-  return this;
-};
-
-/**
- * Set header `field` to `val`, or multiple fields with one object.
- *
- * Examples:
- *
- *      req.get('/')
- *        .set('Accept', 'application/json')
- *        .set('X-API-Key', 'foobar')
- *        .end(callback);
- *
- *      req.get('/')
- *        .set({ Accept: 'application/json', 'X-API-Key': 'foobar' })
- *        .end(callback);
- *
- * @param {String|Object} field
- * @param {String} val
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.set = function(field, val){
-  if (isObject(field)) {
-    for (var key in field) {
-      this.set(key, field[key]);
-    }
-    return this;
-  }
-  this._header[field.toLowerCase()] = val;
-  this.header[field] = val;
-  return this;
-};
-
-/**
- * Remove header `field`.
- *
- * Example:
- *
- *      req.get('/')
- *        .unset('User-Agent')
- *        .end(callback);
- *
- * @param {String} field
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.unset = function(field){
-  delete this._header[field.toLowerCase()];
-  delete this.header[field];
-  return this;
-};
-
-/**
- * Get case-insensitive header `field` value.
- *
- * @param {String} field
- * @return {String}
- * @api private
- */
-
-Request.prototype.getHeader = function(field){
-  return this._header[field.toLowerCase()];
-};
-
-/**
- * Set Content-Type to `type`, mapping values from `request.types`.
- *
- * Examples:
- *
- *      superagent.types.xml = 'application/xml';
- *
- *      request.post('/')
- *        .type('xml')
- *        .send(xmlstring)
- *        .end(callback);
- *
- *      request.post('/')
- *        .type('application/xml')
- *        .send(xmlstring)
- *        .end(callback);
- *
- * @param {String} type
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.type = function(type){
-  this.set('Content-Type', request.types[type] || type);
-  return this;
-};
-
-/**
- * Force given parser
- *
- * Sets the body parser no matter type.
- *
- * @param {Function}
- * @api public
- */
-
-Request.prototype.parse = function(fn){
-  this._parser = fn;
-  return this;
-};
-
-/**
- * Set Accept to `type`, mapping values from `request.types`.
- *
- * Examples:
- *
- *      superagent.types.json = 'application/json';
- *
- *      request.get('/agent')
- *        .accept('json')
- *        .end(callback);
- *
- *      request.get('/agent')
- *        .accept('application/json')
- *        .end(callback);
- *
- * @param {String} accept
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.accept = function(type){
-  this.set('Accept', request.types[type] || type);
-  return this;
-};
-
-/**
- * Set Authorization field value with `user` and `pass`.
- *
- * @param {String} user
- * @param {String} pass
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.auth = function(user, pass){
-  var str = btoa(user + ':' + pass);
-  this.set('Authorization', 'Basic ' + str);
-  return this;
-};
-
-/**
-* Add query-string `val`.
-*
-* Examples:
-*
-*   request.get('/shoes')
-*     .query('size=10')
-*     .query({ color: 'blue' })
-*
-* @param {Object|String} val
-* @return {Request} for chaining
-* @api public
-*/
-
-Request.prototype.query = function(val){
-  if ('string' != typeof val) val = serialize(val);
-  if (val) this._query.push(val);
-  return this;
-};
-
-/**
- * Write the field `name` and `val` for "multipart/form-data"
- * request bodies.
- *
- * ``` js
- * request.post('/upload')
- *   .field('foo', 'bar')
- *   .end(callback);
- * ```
- *
- * @param {String} name
- * @param {String|Blob|File} val
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.field = function(name, val){
-  if (!this._formData) this._formData = new root.FormData();
-  this._formData.append(name, val);
-  return this;
-};
-
-/**
- * Queue the given `file` as an attachment to the specified `field`,
- * with optional `filename`.
- *
- * ``` js
- * request.post('/upload')
- *   .attach(new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: "text/html"}))
- *   .end(callback);
- * ```
- *
- * @param {String} field
- * @param {Blob|File} file
- * @param {String} filename
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.attach = function(field, file, filename){
-  if (!this._formData) this._formData = new root.FormData();
-  this._formData.append(field, file, filename);
-  return this;
-};
-
-/**
- * Send `data`, defaulting the `.type()` to "json" when
- * an object is given.
- *
- * Examples:
- *
- *       // querystring
- *       request.get('/search')
- *         .end(callback)
- *
- *       // multiple data "writes"
- *       request.get('/search')
- *         .send({ search: 'query' })
- *         .send({ range: '1..5' })
- *         .send({ order: 'desc' })
- *         .end(callback)
- *
- *       // manual json
- *       request.post('/user')
- *         .type('json')
- *         .send('{"name":"tj"}')
- *         .end(callback)
- *
- *       // auto json
- *       request.post('/user')
- *         .send({ name: 'tj' })
- *         .end(callback)
- *
- *       // manual x-www-form-urlencoded
- *       request.post('/user')
- *         .type('form')
- *         .send('name=tj')
- *         .end(callback)
- *
- *       // auto x-www-form-urlencoded
- *       request.post('/user')
- *         .type('form')
- *         .send({ name: 'tj' })
- *         .end(callback)
- *
- *       // defaults to x-www-form-urlencoded
-  *      request.post('/user')
-  *        .send('name=tobi')
-  *        .send('species=ferret')
-  *        .end(callback)
- *
- * @param {String|Object} data
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.send = function(data){
-  var obj = isObject(data);
-  var type = this.getHeader('Content-Type');
-
-  // merge
-  if (obj && isObject(this._data)) {
-    for (var key in data) {
-      this._data[key] = data[key];
-    }
-  } else if ('string' == typeof data) {
-    if (!type) this.type('form');
-    type = this.getHeader('Content-Type');
-    if ('application/x-www-form-urlencoded' == type) {
-      this._data = this._data
-        ? this._data + '&' + data
-        : data;
-    } else {
-      this._data = (this._data || '') + data;
-    }
-  } else {
-    this._data = data;
-  }
-
-  if (!obj || isHost(data)) return this;
-  if (!type) this.type('json');
-  return this;
-};
-
-/**
- * Invoke the callback with `err` and `res`
- * and handle arity check.
- *
- * @param {Error} err
- * @param {Response} res
- * @api private
- */
-
-Request.prototype.callback = function(err, res){
-  var fn = this._callback;
-  this.clearTimeout();
-  fn(err, res);
-};
-
-/**
- * Invoke callback with x-domain error.
- *
- * @api private
- */
-
-Request.prototype.crossDomainError = function(){
-  var err = new Error('Origin is not allowed by Access-Control-Allow-Origin');
-  err.crossDomain = true;
-  this.callback(err);
-};
-
-/**
- * Invoke callback with timeout error.
- *
- * @api private
- */
-
-Request.prototype.timeoutError = function(){
-  var timeout = this._timeout;
-  var err = new Error('timeout of ' + timeout + 'ms exceeded');
-  err.timeout = timeout;
-  this.callback(err);
-};
-
-/**
- * Enable transmission of cookies with x-domain requests.
- *
- * Note that for this to work the origin must not be
- * using "Access-Control-Allow-Origin" with a wildcard,
- * and also must set "Access-Control-Allow-Credentials"
- * to "true".
- *
- * @api public
- */
-
-Request.prototype.withCredentials = function(){
-  this._withCredentials = true;
-  return this;
-};
-
-/**
- * Initiate request, invoking callback `fn(res)`
- * with an instanceof `Response`.
- *
- * @param {Function} fn
- * @return {Request} for chaining
- * @api public
- */
-
-Request.prototype.end = function(fn){
-  var self = this;
-  var xhr = this.xhr = request.getXHR();
-  var query = this._query.join('&');
-  var timeout = this._timeout;
-  var data = this._formData || this._data;
-
-  // store callback
-  this._callback = fn || noop;
-
-  // state change
-  xhr.onreadystatechange = function(){
-    if (4 != xhr.readyState) return;
-
-    // In IE9, reads to any property (e.g. status) off of an aborted XHR will
-    // result in the error "Could not complete the operation due to error c00c023f"
-    var status;
-    try { status = xhr.status } catch(e) { status = 0; }
-
-    if (0 == status) {
-      if (self.timedout) return self.timeoutError();
-      if (self.aborted) return;
-      return self.crossDomainError();
-    }
-    self.emit('end');
-  };
-
-  // progress
-  var handleProgress = function(e){
-    if (e.total > 0) {
-      e.percent = e.loaded / e.total * 100;
-    }
-    self.emit('progress', e);
-  };
-  if (this.hasListeners('progress')) {
-    xhr.onprogress = handleProgress;
-  }
-  try {
-    if (xhr.upload && this.hasListeners('progress')) {
-      xhr.upload.onprogress = handleProgress;
-    }
-  } catch(e) {
-    // Accessing xhr.upload fails in IE from a web worker, so just pretend it doesn't exist.
-    // Reported here:
-    // https://connect.microsoft.com/IE/feedback/details/837245/xmlhttprequest-upload-throws-invalid-argument-when-used-from-web-worker-context
-  }
-
-  // timeout
-  if (timeout && !this._timer) {
-    this._timer = setTimeout(function(){
-      self.timedout = true;
-      self.abort();
-    }, timeout);
-  }
-
-  // querystring
-  if (query) {
-    query = request.serializeObject(query);
-    this.url += ~this.url.indexOf('?')
-      ? '&' + query
-      : '?' + query;
-  }
-
-  // initiate request
-  xhr.open(this.method, this.url, true);
-
-  // CORS
-  if (this._withCredentials) xhr.withCredentials = true;
-
-  // body
-  if ('GET' != this.method && 'HEAD' != this.method && 'string' != typeof data && !isHost(data)) {
-    // serialize stuff
-    var contentType = this.getHeader('Content-Type');
-    var serialize = this._parser || request.serialize[contentType ? contentType.split(';')[0] : ''];
-    if (serialize) data = serialize(data);
-  }
-
-  // set header fields
-  for (var field in this.header) {
-    if (null == this.header[field]) continue;
-    xhr.setRequestHeader(field, this.header[field]);
-  }
-
-  // send stuff
-  this.emit('request', this);
-
-  // IE11 xhr.send(undefined) sends 'undefined' string as POST payload (instead of nothing)
-  // We need null here if data is undefined
-  xhr.send(typeof data !== 'undefined' ? data : null);
-  return this;
-};
-
-/**
- * Faux promise support
- *
- * @param {Function} fulfill
- * @param {Function} reject
- * @return {Request}
- */
-
-Request.prototype.then = function (fulfill, reject) {
-  return this.end(function(err, res) {
-    err ? reject(err) : fulfill(res);
-  });
-}
-
-/**
- * Expose `Request`.
- */
-
-request.Request = Request;
-
-/**
- * Issue a request:
- *
- * Examples:
- *
- *    request('GET', '/users').end(callback)
- *    request('/users').end(callback)
- *    request('/users', callback)
- *
- * @param {String} method
- * @param {String|Function} url or callback
- * @return {Request}
- * @api public
- */
-
-function request(method, url) {
-  // callback
-  if ('function' == typeof url) {
-    return new Request('GET', method).end(url);
-  }
-
-  // url first
-  if (1 == arguments.length) {
-    return new Request('GET', method);
-  }
-
-  return new Request(method, url);
-}
-
-/**
- * GET `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.get = function(url, data, fn){
-  var req = request('GET', url);
-  if ('function' == typeof data) fn = data, data = null;
-  if (data) req.query(data);
-  if (fn) req.end(fn);
-  return req;
-};
-
-/**
- * HEAD `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.head = function(url, data, fn){
-  var req = request('HEAD', url);
-  if ('function' == typeof data) fn = data, data = null;
-  if (data) req.send(data);
-  if (fn) req.end(fn);
-  return req;
-};
-
-/**
- * DELETE `url` with optional callback `fn(res)`.
- *
- * @param {String} url
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-function del(url, fn){
-  var req = request('DELETE', url);
-  if (fn) req.end(fn);
-  return req;
-};
-
-request.del = del;
-request.delete = del;
-
-/**
- * PATCH `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed} data
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.patch = function(url, data, fn){
-  var req = request('PATCH', url);
-  if ('function' == typeof data) fn = data, data = null;
-  if (data) req.send(data);
-  if (fn) req.end(fn);
-  return req;
-};
-
-/**
- * POST `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed} data
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.post = function(url, data, fn){
-  var req = request('POST', url);
-  if ('function' == typeof data) fn = data, data = null;
-  if (data) req.send(data);
-  if (fn) req.end(fn);
-  return req;
-};
-
-/**
- * PUT `url` with optional `data` and callback `fn(res)`.
- *
- * @param {String} url
- * @param {Mixed|Function} data or fn
- * @param {Function} fn
- * @return {Request}
- * @api public
- */
-
-request.put = function(url, data, fn){
-  var req = request('PUT', url);
-  if ('function' == typeof data) fn = data, data = null;
-  if (data) req.send(data);
-  if (fn) req.end(fn);
-  return req;
-};
-
-/**
- * Expose `request`.
- */
-
-module.exports = request;
-
-},{"emitter":2,"reduce":3}],2:[function(require,module,exports){
-
-/**
- * Expose `Emitter`.
- */
-
-module.exports = Emitter;
-
-/**
- * Initialize a new `Emitter`.
- *
- * @api public
- */
-
-function Emitter(obj) {
-  if (obj) return mixin(obj);
-};
-
-/**
- * Mixin the emitter properties.
- *
- * @param {Object} obj
- * @return {Object}
- * @api private
- */
-
-function mixin(obj) {
-  for (var key in Emitter.prototype) {
-    obj[key] = Emitter.prototype[key];
-  }
-  return obj;
-}
-
-/**
- * Listen on the given `event` with `fn`.
- *
- * @param {String} event
- * @param {Function} fn
- * @return {Emitter}
- * @api public
- */
-
-Emitter.prototype.on =
-Emitter.prototype.addEventListener = function(event, fn){
-  this._callbacks = this._callbacks || {};
-  (this._callbacks[event] = this._callbacks[event] || [])
-    .push(fn);
-  return this;
-};
-
-/**
- * Adds an `event` listener that will be invoked a single
- * time then automatically removed.
- *
- * @param {String} event
- * @param {Function} fn
- * @return {Emitter}
- * @api public
- */
-
-Emitter.prototype.once = function(event, fn){
-  var self = this;
-  this._callbacks = this._callbacks || {};
-
-  function on() {
-    self.off(event, on);
-    fn.apply(this, arguments);
-  }
-
-  on.fn = fn;
-  this.on(event, on);
-  return this;
-};
-
-/**
- * Remove the given callback for `event` or all
- * registered callbacks.
- *
- * @param {String} event
- * @param {Function} fn
- * @return {Emitter}
- * @api public
- */
-
-Emitter.prototype.off =
-Emitter.prototype.removeListener =
-Emitter.prototype.removeAllListeners =
-Emitter.prototype.removeEventListener = function(event, fn){
-  this._callbacks = this._callbacks || {};
-
-  // all
-  if (0 == arguments.length) {
-    this._callbacks = {};
-    return this;
-  }
-
-  // specific event
-  var callbacks = this._callbacks[event];
-  if (!callbacks) return this;
-
-  // remove all handlers
-  if (1 == arguments.length) {
-    delete this._callbacks[event];
-    return this;
-  }
-
-  // remove specific handler
-  var cb;
-  for (var i = 0; i < callbacks.length; i++) {
-    cb = callbacks[i];
-    if (cb === fn || cb.fn === fn) {
-      callbacks.splice(i, 1);
-      break;
-    }
-  }
-  return this;
-};
-
-/**
- * Emit `event` with the given args.
- *
- * @param {String} event
- * @param {Mixed} ...
- * @return {Emitter}
- */
-
-Emitter.prototype.emit = function(event){
-  this._callbacks = this._callbacks || {};
-  var args = [].slice.call(arguments, 1)
-    , callbacks = this._callbacks[event];
-
-  if (callbacks) {
-    callbacks = callbacks.slice(0);
-    for (var i = 0, len = callbacks.length; i < len; ++i) {
-      callbacks[i].apply(this, args);
-    }
-  }
-
-  return this;
-};
-
-/**
- * Return array of callbacks for `event`.
- *
- * @param {String} event
- * @return {Array}
- * @api public
- */
-
-Emitter.prototype.listeners = function(event){
-  this._callbacks = this._callbacks || {};
-  return this._callbacks[event] || [];
-};
-
-/**
- * Check if this emitter has `event` handlers.
- *
- * @param {String} event
- * @return {Boolean}
- * @api public
- */
-
-Emitter.prototype.hasListeners = function(event){
-  return !! this.listeners(event).length;
-};
-
-},{}],3:[function(require,module,exports){
-
-/**
- * Reduce `arr` with `fn`.
- *
- * @param {Array} arr
- * @param {Function} fn
- * @param {Mixed} initial
- *
- * TODO: combatible error handling?
- */
-
-module.exports = function(arr, fn, initial){  
-  var idx = 0;
-  var len = arr.length;
-  var curr = arguments.length == 3
-    ? initial
-    : arr[idx++];
-
-  while (idx < len) {
-    curr = fn.call(null, curr, arr[idx], ++idx, arr);
-  }
-  
-  return curr;
-};
-},{}],4:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-function _toArray(arr) { return Array.isArray(arr) ? arr : Array.from(arr); }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-function promiseWaterfall(_ref) {
-  var _ref2 = _toArray(_ref);
-
-  var resolvedPromise = _ref2[0];
-
-  var tasks = _ref2.slice(1);
-
-  var finalTaskPromise = tasks.reduce(function (prevTaskPromise, task) {
-    return prevTaskPromise.then(task);
-  }, resolvedPromise(1)); // initial value
-
-  return finalTaskPromise;
-}
-
-var _default = (function () {
-  function _default(opts) {
-    _classCallCheck(this, _default);
-
-    // Dictates in what order different plugin types are ran:
-    this.types = ['presetter', 'selecter', 'uploader'];
-
-    // Container for different types of plugins
-    this.plugins = {};
-  }
-
-  _createClass(_default, [{
-    key: 'use',
-    value: function use(Plugin, opts) {
-      // Instantiate
-      var plugin = new Plugin(this, opts);
-      this.plugins[plugin.type] = this.plugins[plugin.type] || [];
-      this.plugins[plugin.type].push(plugin);
-
-      return this;
-    }
-  }, {
-    key: 'setProgress',
-    value: function setProgress(plugin, percentage) {
-      // Any plugin can call this via `this.core.setProgress(this, precentage)`
-      console.log(plugin.type + ' plugin ' + plugin.name + ' set the progress to ' + percentage);
-      return this;
-    }
-
-    // Runs all plugins of the same type in parallel
-  }, {
-    key: 'runType',
-    value: function runType(type, files) {
-      console.dir({
-        method: 'Transloadit.runType',
-        type: type,
-        files: files
-        // cb    : cb
-      });
-
-      var methods = [];
-      for (var p in this.plugins[type]) {
-        var plugin = this.plugins[type][p];
-        methods.push(plugin.run.call(plugin, files));
-      }
-
-      return Promise.all(methods);
-
-      // const methods = this.plugins[type].map(plugin => plugin.run.bind(plugin, files));
-
-      // async.parallel(methods, cb);
-    }
-
-    // Runs a waterfall of runType plugin packs, like so:
-    // All preseters(data) --> All selecters(data) --> All uploaders(data) --> done
-  }, {
-    key: 'run',
-    value: function run() {
-      var _this = this;
-
-      console.dir({
-        method: 'Transloadit.run'
-      });
-
-      var typeMethods = [];
-      // typeMethods.push(async.constant([]));
-
-      // for (let t in this.types) {
-      //   const type = this.types[t];
-      //   typeMethods.push(this.runType.bind(this, type));
-      // }
-
-      this.types.forEach(function (type) {
-        if (_this.plugins[type]) {
-          typeMethods.push(_this.runType.bind(_this, type));
-        }
-      });
-
-      promiseWaterfall(typeMethods).then(function (result) {
-        return console.log(result);
-      })['catch'](function (error) {
-        return console.error(error);
-      });
-
-      // async.waterfall(typeMethods, function (err, finalFiles) {
-      //   console.dir({
-      //     err       : err ,
-      //     finalFiles: finalFiles
-      //   });
-      // });
-    }
-  }]);
-
-  return _default;
-})();
-
-exports['default'] = _default;
-module.exports = exports['default'];
-
-},{}],5:[function(require,module,exports){
-// This is how we roll $('.element').toggleClass in non-jQuery world
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-function toggleClass(el, className) {
-  if (el.classList) {
-    el.classList.toggle(className);
-  } else {
-    var classes = el.className.split(' ');
-    var existingIndex = classes.indexOf(className);
-
-    if (existingIndex >= 0) {
-      classes.splice(existingIndex, 1);
-    } else {
-      classes.push(className);
-      el.className = classes.join(' ');
-    }
-  }
-}
-
-function addClass(el, className) {
-  if (el.classList) {
-    el.classList.add(className);
-  } else {
-    el.className += ' ' + className;
-  }
-}
-
-function removeClass(el, className) {
-  if (el.classList) {
-    el.classList.remove(className);
-  } else {
-    el.className = el.className.replace(new RegExp('(^|\\b)' + className.split(' ').join('|') + '(\\b|$)', 'gi'), ' ');
-  }
-}
-
-// $form.on('drag dragstart dragend dragover dragenter dragleave drop');
-function addListenerMulti(el, events, func) {
-  var eventsArray = events.split(' ');
-  for (var _event in eventsArray) {
-    el.addEventListener(eventsArray[_event], func, false);
-  }
-}
-
-exports['default'] = {
-  toggleClass: toggleClass,
-  addClass: addClass,
-  removeClass: removeClass,
-  addListenerMulti: addListenerMulti
-};
-module.exports = exports['default'];
-
-},{}],6:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-var _Transloadit = require('./Transloadit');
-
-var _Transloadit2 = _interopRequireDefault(_Transloadit);
-
-exports['default'] = _Transloadit2['default'];
-module.exports = exports['default'];
-
-},{"./Transloadit":4}],7:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-var _core = require('./core');
-
-var _core2 = _interopRequireDefault(_core);
-
-var _plugins = require('./plugins');
-
-var _plugins2 = _interopRequireDefault(_plugins);
-
-exports['default'] = {
-  Core: _core2['default'],
-  plugins: _plugins2['default']
-};
-module.exports = exports['default'];
-
-},{"./core":6,"./plugins":13}],8:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var _coreUtils = require('../core/Utils');
-
-var _coreUtils2 = _interopRequireDefault(_coreUtils);
-
-var _TransloaditPlugin2 = require('./TransloaditPlugin');
-
-var _TransloaditPlugin3 = _interopRequireDefault(_TransloaditPlugin2);
-
-// import Tus from 'tus-js-client';
-// console.log('pizza', Tus);
-
-var DragDrop = (function (_TransloaditPlugin) {
-  _inherits(DragDrop, _TransloaditPlugin);
-
-  function DragDrop(core, opts) {
-    _classCallCheck(this, DragDrop);
-
-    _get(Object.getPrototypeOf(DragDrop.prototype), 'constructor', this).call(this, core, opts);
-    this.type = 'selecter';
-
-    // set default options
-    var defaultOptions = {
-      bla: 'blabla',
-      autoSubmit: true,
-      modal: true
-    };
-
-    // merge default options with the ones set by user
-    this.opts = defaultOptions;
-    Object.assign(this.opts, opts);
-
-    console.log(this.opts);
-
-    // get the element where Drag & Drop event will occur
-    this.dropzone = document.querySelectorAll(this.opts.selector)[0];
-    this.dropzoneInput = document.querySelectorAll('.UppyDragDrop-input')[0];
-
-    this.status = document.querySelectorAll('.UppyDragDrop-status')[0];
-
-    this.isDragDropSupported = this.checkDragDropSupport();
-
-    // crazy stuff so that ‘this’ will behave in class
-    this.listenForEvents = this.listenForEvents.bind(this);
-    this.handleDrop = this.handleDrop.bind(this);
-    this.checkDragDropSupport = this.checkDragDropSupport.bind(this);
-    this.upload = this.upload.bind(this);
-    this.handleInputChange = this.handleInputChange.bind(this);
-  }
-
-  /**
-   * Checks if the browser supports Drag & Drop
-   */
-
-  _createClass(DragDrop, [{
-    key: 'checkDragDropSupport',
-    value: function checkDragDropSupport() {
-      var div = document.createElement('div');
-      return ('draggable' in div || 'ondragstart' in div && 'ondrop' in div) && 'FormData' in window && 'FileReader' in window;
-    }
-  }, {
-    key: 'listenForEvents',
-    value: function listenForEvents() {
-      var _this = this;
-
-      if (this.isDragDropSupported) {
-        _coreUtils2['default'].addClass(this.dropzone, 'is-dragdrop-supported');
-      }
-
-      // prevent default actions for all drag & drop events
-      _coreUtils2['default'].addListenerMulti(this.dropzone, 'drag dragstart dragend dragover dragenter dragleave drop', function (e) {
-        e.preventDefault();
-        e.stopPropagation();
-      });
-
-      // Toggle is-dragover state when files are dragged over or dropped
-      _coreUtils2['default'].addListenerMulti(this.dropzone, 'dragover dragenter', function () {
-        _coreUtils2['default'].addClass(_this.dropzone, 'is-dragover');
-      });
-
-      _coreUtils2['default'].addListenerMulti(this.dropzone, 'dragleave dragend drop', function () {
-        _coreUtils2['default'].removeClass(_this.dropzone, 'is-dragover');
-      });
-
-      this.dropzone.addEventListener('drop', this.handleDrop);
-
-      this.dropzoneInput.addEventListener('change', this.handleInputChange);
-
-      console.log('waiting for some files to be dropped on ' + this.opts.selector);
-    }
-
-    // Toggle is-dragover state when files are dragged over or dropped
-    // in this case — add/remove 'is-dragover' class
-    // toggleDragoverState(e) {
-    //   toggleClass(this.dropzone, 'is-dragover');
-    // }
-
-  }, {
-    key: 'displayStatus',
-    value: function displayStatus(status) {
-      this.status.innerHTML = status;
-    }
-  }, {
-    key: 'handleDrop',
-    value: function handleDrop(e) {
-      console.log('all right, someone dropped something here...');
-      var files = e.dataTransfer.files;
-      var formData = new FormData(this.dropzone);
-      // console.log('pizza', formData);
-
-      for (var i = 0; i < files.length; i++) {
-        formData.append('file', files[i]);
-        console.log('pizza', files[i]);
-      }
-
-      this.upload(formData);
-    }
-  }, {
-    key: 'handleInputChange',
-    value: function handleInputChange() {
-      // const fileInput = document.querySelectorAll('.UppyDragDrop-input')[0];
-      var formData = new FormData(this.dropzone);
-      console.log('pizza', formData);
-
-      this.upload(formData);
-    }
-  }, {
-    key: 'upload',
-    value: function upload(data) {
-      var _this2 = this;
-
-      this.displayStatus('Uploading...');
-
-      var request = new XMLHttpRequest();
-      request.open('POST', 'http://api2.transloadit.com', true);
-      request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
-
-      request.addEventListener('load', function () {
-        console.log('fucking done!');
-        _this2.displayStatus('Done.');
-      });
-
-      request.addEventListener('load', function () {
-        _this2.displayStatus('Done.');
-      });
-
-      request.addEventListener('error', function () {
-        console.log('fucking error!');
-      });
-
-      request.send(data);
-
-      // Create a new tus upload
-      // const upload = new Tus.Upload(data, {
-      //   endpoint: 'http://master.tus.io:8080',
-      //   onError: function(error) {
-      //     console.log('Failed because: ' + error);
-      //   },
-      //   onProgress: function(bytesUploaded, bytesTotal) {
-      //     var percentage = (bytesUploaded / bytesTotal * 100).toFixed(2);
-      //     console.log(bytesUploaded, bytesTotal, percentage + '%');
-      //   },
-      //   onSuccess: function() {
-      //     console.log('Download %s from %s', upload.file.name, upload.url);
-      //   }
-      // });
-      //
-      // // Start the upload
-      // upload.start();
-    }
-  }, {
-    key: 'run',
-    value: function run(files) {
-      console.dir({
-        method: 'DragDrop.run',
-        files: files
-        // done  : done
-      });
-
-      console.log('DragDrop running!');
-      // console.log(files);
-      this.listenForEvents();
-      this.core.setProgress(this, 0);
-      var selected = [{ name: 'lolcat.jpeg' }];
-      this.core.setProgress(this, 100);
-      // return selected;
-      // done(null, 'done with DragDrop');
-      return Promise.resolve(files);
-    }
-  }]);
-
-  return DragDrop;
-})(_TransloaditPlugin3['default']);
-
-exports['default'] = DragDrop;
-module.exports = exports['default'];
-
-},{"../core/Utils":5,"./TransloaditPlugin":11}],9:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-var _superagent = require('superagent');
-
-var _superagent2 = _interopRequireDefault(_superagent);
-
-var DropboxPlugin = (function () {
-  function DropboxPlugin() {
-    _classCallCheck(this, DropboxPlugin);
-
-    this.authenticate = this.authenticate.bind(this);
-    this.connect = this.connect.bind(this);
-    this.render = this.render.bind(this);
-    this.files = [];
-    this.currentDir = '/';
-  }
-
-  _createClass(DropboxPlugin, [{
-    key: 'connect',
-    value: function connect(target) {
-      this._target = document.getElementById(target);
-
-      this.client = new Dropbox.Client({ key: 'b7dzc9ei5dv5hcv', token: '' });
-      this.client.authDriver(new Dropbox.AuthDriver.Redirect());
-      this.authenticate();
-
-      if (this.client.credentials().token) {
-        this.getDirectory();
-      }
-    }
-  }, {
-    key: 'authenticate',
-    value: function authenticate() {
-      this.client.authenticate();
-    }
-  }, {
-    key: 'addFile',
-    value: function addFile() {}
-  }, {
-    key: 'getDirectory',
-    value: function getDirectory() {
-      var _this = this;
-
-      _superagent2['default'].get('https://api18.dropbox.com/1/metadata/auto').query({
-        client_id: 'b7dzc9ei5dv5hcv',
-        token: this.client.credentials().token
-      }).set('Content-Type', 'application/json').end(function (err, res) {
-        console.log(res);
-      });
-
-      return this.client.readdir(this.currentDir, function (error, entries, stat, statFiles) {
-        if (error) {
-          return showError(error); // Something went wrong.
-        }
-        return _this.render(statFiles);
-      });
-    }
-  }, {
-    key: 'run',
-    value: function run() {}
-  }, {
-    key: 'render',
-    value: function render(files) {
-      var _this2 = this;
-
-      // for each file in the directory, create a list item element
-      var elems = files.map(function (file, i) {
-        var icon = file.isFolder ? 'folder' : 'file';
-        return '<li data-type="' + icon + '" data-name="' + file.name + '"><span>' + icon + ' : </span><span> ' + file.name + '</span></li>';
-      });
-
-      // appends the list items to the target
-      this._target.innerHTML = elems.sort().join('');
-
-      if (this.currentDir.length > 1) {
-        var _parent = document.createElement('LI');
-        _parent.setAttribute('data-type', 'parent');
-        _parent.innerHTML = '<span>...</span>';
-        this._target.appendChild(_parent);
-      }
-
-      // add an onClick to each list item
-      var fileElems = this._target.querySelectorAll('li');
-
-      Array.prototype.forEach.call(fileElems, function (element) {
-        var type = element.getAttribute('data-type');
-
-        if (type === 'file') {
-          element.addEventListener('click', function () {
-            _this2.files.push(element.getAttribute('data-name'));
-            console.dir('files: ' + _this2.files);
-          });
-        } else {
-          element.addEventListener('dblclick', function () {
-            var length = _this2.currentDir.split('/').length;
-
-            if (type === 'folder') {
-              _this2.currentDir = '' + _this2.currentDir + element.getAttribute('data-name') + '/';
-            } else if (type === 'parent') {
-              _this2.currentDir = _this2.currentDir.split('/').slice(0, length - 2).join('/') + '/';
-            }
-            console.log(_this2.currentDir);
-            _this2.getDirectory();
-          });
-        }
-      });
-    }
-  }]);
-
-  return DropboxPlugin;
-})();
-
-exports['default'] = new DropboxPlugin();
-module.exports = exports['default'];
-
-},{"superagent":1}],10:[function(require,module,exports){
-'use strict';
-
-var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var _TransloaditPlugin2 = require('./TransloaditPlugin');
-
-var _TransloaditPlugin3 = _interopRequireDefault(_TransloaditPlugin2);
-
-var TransloaditBasic = (function (_TransloaditPlugin) {
-  _inherits(TransloaditBasic, _TransloaditPlugin);
-
-  function TransloaditBasic(core, opts) {
-    _classCallCheck(this, TransloaditBasic);
-
-    _get(Object.getPrototypeOf(TransloaditBasic.prototype), 'constructor', this).call(this, core, opts);
-    this.type = 'presetter';
-    this.core.use(DragDrop, { modal: true, wait: true }).use(Tus10, { endpoint: 'http://master.tus.io:8080' });
-  }
-
-  return TransloaditBasic;
-})(_TransloaditPlugin3['default']);
-
-},{"./TransloaditPlugin":11}],11:[function(require,module,exports){
-"use strict";
-
-Object.defineProperty(exports, "__esModule", {
-  value: true
-});
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var TransloaditPlugin = (function () {
-  // This contains boilerplate that all TransloaditPlugins share - and should not be used
-  // directly. It also shows which methods final plugins should implement/override,
-  // this deciding on structure.
-
-  function TransloaditPlugin(core, opts) {
-    _classCallCheck(this, TransloaditPlugin);
-
-    this.core = core;
-    this.opts = opts;
-    this.name = this.constructor.name;
-  }
-
-  _createClass(TransloaditPlugin, [{
-    key: "run",
-    value: function run(files) {
-      return files;
-    }
-  }]);
-
-  return TransloaditPlugin;
-})();
-
-exports["default"] = TransloaditPlugin;
-module.exports = exports["default"];
-
-},{}],12:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ('value' in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();
-
-var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
-
-var _TransloaditPlugin2 = require('./TransloaditPlugin');
-
-var _TransloaditPlugin3 = _interopRequireDefault(_TransloaditPlugin2);
-
-var Tus10 = (function (_TransloaditPlugin) {
-  _inherits(Tus10, _TransloaditPlugin);
-
-  function Tus10(core, opts) {
-    _classCallCheck(this, Tus10);
-
-    _get(Object.getPrototypeOf(Tus10.prototype), 'constructor', this).call(this, core, opts);
-    this.type = 'uploader';
-  }
-
-  _createClass(Tus10, [{
-    key: 'run',
-    value: function run(files) {
-      // console.log(files);
-      this.core.setProgress(this, 0);
-      var uploaded = [];
-      // for (var i in files) {
-      //   var file = files[i];
-      //   this.core.setProgress(this, (i * 1) + 1);
-      //   uploaded[i]     = file;
-      //   uploaded[i].url = this.opts.endpoint + '/uploaded/' + file.name;
-      // }
-      this.core.setProgress(this, 100);
-
-      // done(null, 'done with Tus');
-      return Promise.resolve(files);
-
-      // return uploaded;
-    }
-  }]);
-
-  return Tus10;
-})(_TransloaditPlugin3['default']);
-
-exports['default'] = Tus10;
-module.exports = exports['default'];
-
-},{"./TransloaditPlugin":11}],13:[function(require,module,exports){
-'use strict';
-
-Object.defineProperty(exports, '__esModule', {
-  value: true
-});
-
-function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
-
-var _TransloaditPlugin = require('./TransloaditPlugin');
-
-var _TransloaditPlugin2 = _interopRequireDefault(_TransloaditPlugin);
-
-var _DragDrop = require('./DragDrop');
-
-var _DragDrop2 = _interopRequireDefault(_DragDrop);
-
-var _Dropbox = require('./Dropbox');
-
-var _Dropbox2 = _interopRequireDefault(_Dropbox);
-
-var _TransloaditBasic = require('./TransloaditBasic');
-
-var _TransloaditBasic2 = _interopRequireDefault(_TransloaditBasic);
-
-var _Tus10 = require('./Tus10');
-
-var _Tus102 = _interopRequireDefault(_Tus10);
-
-exports['default'] = {
-  TransloaditPlugin: _TransloaditPlugin2['default'],
-  DropboxPlugin: _Dropbox2['default'],
-  DragDrop: _DragDrop2['default'],
-  TransloaditBasic: _TransloaditBasic2['default'],
-  Tus10: _Tus102['default']
-};
-module.exports = exports['default'];
-
-},{"./DragDrop":8,"./Dropbox":9,"./TransloaditBasic":10,"./TransloaditPlugin":11,"./Tus10":12}]},{},[7])(7)
-});

+ 37 - 0
website/src/guide/contributing.md

@@ -4,6 +4,18 @@ order: 20
 title: "Contributing Guidelines"
 title: "Contributing Guidelines"
 ---
 ---
 
 
+## Uppy Development
+
+First clone and install the project:
+
+```bash
+git clone git@github.com:transloadit/uppy.git
+cd uppy
+npm install
+```
+
+Our website's examples section is also our playground, read "Website Development"'s "Getting Started" section to get up and running.
+
 ## CSS Guidelines
 ## CSS Guidelines
 
 
 The CSS standards followed in this project closely resemble those from [Medium's CSS Guidelines](https://gist.github.com/fat/a47b882eb5f84293c4ed). If it's not mentioned here, follow their guidelines.
 The CSS standards followed in this project closely resemble those from [Medium's CSS Guidelines](https://gist.github.com/fat/a47b882eb5f84293c4ed). If it's not mentioned here, follow their guidelines.
@@ -106,3 +118,28 @@ h1 {
   width: 940px;
   width: 940px;
 }
 }
 ```
 ```
+
+
+## Website Development
+
+We keep the [uppyjs.io](http://uppyjs.io) website in `./website` for so it's easy to keep docs & code in sync as we're still iterating at high velocity. For those reading this screaming murder, [HashiCorp does this](https://github.com/hashicorp/terraform/tree/master/website) for all their projects, and it's working well for them on a scale vastly more impressive than Uppy's.
+
+The site is built with [Hexo](http://hexo.io/), and Travis automatically deploys this onto GitHub Pages (it overwrites the `gh-pages` branch with Hexo's build at every change to `master`). The content is written in Markdown and located in `./website/src`. Feel free to fork & hack!  
+
+Even though bundled in this repo, the website is regarded as a separate project. So it has its own `package.json` and we aim keep the surface where the two projects interface as small as possible. `./website/update.js` is called during website builds to inject the Uppy knowledge into the site.
+
+### Getting Started
+
+It's recommended to exclude `./website/public/` from your editor if you want efficient searches.
+
+For local previews on http://127.0.0.1:4000 type:
+
+```bash
+npm run web
+```
+
+This will start Hexo and rebuilds the site as you save. If you also want to work on examples / Uppy itself you then open a second tab in which you type:
+
+```bash
+npm run watch:examples
+```

+ 20 - 0
website/src/guide/faq.md

@@ -0,0 +1,20 @@
+---
+type: guide
+order: 21
+title: "FAQ"
+---
+
+## Why does your site look like vuejs.org?
+
+The website is currently a clone of Yuxi Evan You's wonderful [Vue.js](http://vuejs.org/) website ([view license](website/VUEORG_LICENSE)) - just so we can hit the ground running in terms of Haxo boilerplate, etc. Obviously as soon as possible, we'll start rolling out our own layout & content and make this place our own. We'll keep the Vue website MIT license & credit in the footer in tact of course.
+
+## What does Travis do?
+
+Travis should:
+
+- [x] check out code 
+- [x] build project
+- [ ] run unit tests
+- [ ] run acceptance tests
+- [x] copy/install the built project into any `examples/*/`
+- [x] deploy the examples to our hackathon S3 bucket in a folder named by branch (http://hackathon.transloadit.com/uppy/master/index.html), so we can all play with the current state of the project & examples per branch, without installing everything locally.

+ 6 - 0
website/update.js

@@ -25,3 +25,9 @@ fs.writeFileSync(
       return 'uppy_' + p1 + '_size: "' + (sizes[p1] || 99999 ) + '"'
       return 'uppy_' + p1 + '_size: "' + (sizes[p1] || 99999 ) + '"'
     })
     })
 )
 )
+
+// Copy latest uppy version into website so the CDN example can use it
+fs.writeFileSync(
+  './themes/uppy/source/js/uppy.js',
+  fs.readFileSync(locations.dev, 'utf-8')
+);

+ 2 - 2
website/watch.js → website/watch-examples.js

@@ -1,5 +1,5 @@
 /**
 /**
- * watch.js
+ * watch-examples.js
  * --------
  * --------
  * Searches for each example's `src/js/app.js` file.
  * Searches for each example's `src/js/app.js` file.
  * Creates a new watchify instance for each `app.js`.
  * Creates a new watchify instance for each `app.js`.
@@ -27,7 +27,7 @@ var dest = 'static/js/app.js';
 var pattern = 'src/examples/**/' + src;
 var pattern = 'src/examples/**/' + src;
 
 
 // Find each app.js file with glob.
 // Find each app.js file with glob.
-// 'website/' glob is for when calling `node website/watch.js` from root.
+// 'website/' glob is for when calling `node website/watch-examples.js` from root.
 glob([pattern, 'website/' + pattern], function(err, files) {
 glob([pattern, 'website/' + pattern], function(err, files) {
   if (err) throw new Error(err);
   if (err) throw new Error(err);