First commit
authorBenjamin Auder <benjamin.auder@somewhere>
Tue, 13 Nov 2018 06:56:28 +0000 (07:56 +0100)
committerBenjamin Auder <benjamin.auder@somewhere>
Tue, 13 Nov 2018 06:56:28 +0000 (07:56 +0100)
89 files changed:
.gitattributes [new file with mode: 0644]
.gitfat [new file with mode: 0644]
.gitignore [new file with mode: 0644]
README.md [new file with mode: 0644]
app.js [new file with mode: 0644]
bin/www [new file with mode: 0755]
gulpfile.js [new file with mode: 0644]
package-lock.json [new file with mode: 0644]
package.json [new file with mode: 0644]
public/images/favicon/README [new file with mode: 0644]
public/images/favicon/android-chrome-192x192.png [new file with mode: 0644]
public/images/favicon/android-chrome-512x512.png [new file with mode: 0644]
public/images/favicon/apple-touch-icon.png [new file with mode: 0644]
public/images/favicon/browserconfig.xml [new file with mode: 0644]
public/images/favicon/favicon-16x16.png [new file with mode: 0644]
public/images/favicon/favicon-32x32.png [new file with mode: 0644]
public/images/favicon/favicon.ico [new file with mode: 0644]
public/images/favicon/manifest.json [new file with mode: 0644]
public/images/favicon/mstile-150x150.png [new file with mode: 0644]
public/images/favicon/safari-pinned-tab.svg [new file with mode: 0644]
public/images/mark.svg [new file with mode: 0644]
public/images/pieces/Checkered/cb.svg [new file with mode: 0644]
public/images/pieces/Checkered/cn.svg [new file with mode: 0644]
public/images/pieces/Checkered/cp.svg [new file with mode: 0644]
public/images/pieces/Checkered/cq.svg [new file with mode: 0644]
public/images/pieces/Checkered/cr.svg [new file with mode: 0644]
public/images/pieces/LICENSE [new file with mode: 0644]
public/images/pieces/bb.svg [new file with mode: 0644]
public/images/pieces/bk.svg [new file with mode: 0644]
public/images/pieces/bn.svg [new file with mode: 0644]
public/images/pieces/bp.svg [new file with mode: 0644]
public/images/pieces/bq.svg [new file with mode: 0644]
public/images/pieces/br.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Alt26.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Gdt45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Gll45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Ult45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Zdl45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_Zll45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_adt45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_alt45.svg [new file with mode: 0644]
public/images/pieces/new/Chess_clt45.svg [new file with mode: 0644]
public/images/pieces/new/camel-animal-pet-desert-39f82768c72363eb.svg [new file with mode: 0644]
public/images/pieces/new/camel-animal-pet-desert-3f04e77f40eba40d.svg [new file with mode: 0644]
public/images/pieces/new/camel-animal-wildlife-34b2662eb81cfec3.svg [new file with mode: 0644]
public/images/pieces/new/camel-animal-wildlife-3b15afb5e788b9ec.svg [new file with mode: 0644]
public/images/pieces/new/unicorn-myth-legend-halloween-fantasy-37ec614cb63bc127.svg [new file with mode: 0644]
public/images/pieces/new/wildebeest-animal-wild-wildlife-face-326845431b848a31.svg [new file with mode: 0644]
public/images/pieces/new/wildebeest-animal-wildlife-31b7b8fe2ffee150.svg [new file with mode: 0644]
public/images/pieces/wb.svg [new file with mode: 0644]
public/images/pieces/wk.svg [new file with mode: 0644]
public/images/pieces/wn.svg [new file with mode: 0644]
public/images/pieces/wp.svg [new file with mode: 0644]
public/images/pieces/wq.svg [new file with mode: 0644]
public/images/pieces/wr.svg [new file with mode: 0644]
public/images/tmp_checkered/cb.png [new file with mode: 0644]
public/images/tmp_checkered/cn.png [new file with mode: 0644]
public/images/tmp_checkered/cp.png [new file with mode: 0644]
public/images/tmp_checkered/cq.png [new file with mode: 0644]
public/images/tmp_checkered/cr.png [new file with mode: 0644]
public/images/tmp_checkered/no_ck.png [new file with mode: 0644]
public/javascripts/base_rules.js [new file with mode: 0644]
public/javascripts/components/game.js [new file with mode: 0644]
public/javascripts/components/rules.js [new file with mode: 0644]
public/javascripts/components/variantSummary.js [new file with mode: 0644]
public/javascripts/index.js [new file with mode: 0644]
public/javascripts/utils/array.js [new file with mode: 0644]
public/javascripts/utils/socket_url.js.dist [new file with mode: 0644]
public/javascripts/variants/Atomic.js [new file with mode: 0644]
public/javascripts/variants/Checkered.js [new file with mode: 0644]
public/javascripts/variants/Chess960.js [new file with mode: 0644]
public/javascripts/variants/Zen.js [new file with mode: 0644]
public/sounds/SOURCE [new file with mode: 0644]
public/sounds/chessmove1.mp3 [new file with mode: 0644]
public/sounds/newgame.mp3 [new file with mode: 0644]
public/stylesheets/index.sass [new file with mode: 0644]
public/stylesheets/layout.sass [new file with mode: 0644]
public/stylesheets/variant.sass [new file with mode: 0644]
routes/all.js [new file with mode: 0644]
sockets.js [new file with mode: 0644]
variants.js [new file with mode: 0644]
views/error.pug [new file with mode: 0644]
views/index.pug [new file with mode: 0644]
views/layout.pug [new file with mode: 0644]
views/rules/Atomic.pug [new file with mode: 0644]
views/rules/Checkered.pug [new file with mode: 0644]
views/rules/Chess960.pug [new file with mode: 0644]
views/rules/Zen.pug [new file with mode: 0644]
views/variant.pug [new file with mode: 0644]

diff --git a/.gitattributes b/.gitattributes
new file mode 100644 (file)
index 0000000..d268ba5
--- /dev/null
@@ -0,0 +1,6 @@
+*.pdf filter=fat
+*.zip filter=fat
+*.tar.xz filter=fat
+*.wav filter=fat
+*.mp3 filter=fat
+*.png filter=fat
diff --git a/.gitfat b/.gitfat
new file mode 100644 (file)
index 0000000..53d69a1
--- /dev/null
+++ b/.gitfat
@@ -0,0 +1,2 @@
+[rsync]
+remote = gitfat@auder.net:~/files/vchess
diff --git a/.gitignore b/.gitignore
new file mode 100644 (file)
index 0000000..6a9f580
--- /dev/null
@@ -0,0 +1,72 @@
+# Logs
+logs
+*.log
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# Runtime data
+pids
+*.pid
+*.seed
+*.pid.lock
+
+# Temp files
+*.swp
+*~
+
+# socket URL file
+/public/javascripts/utils/socket_url.js
+
+# CSS generated files
+/public/stylesheets/*.map
+/public/stylesheets/*.css
+
+# Directory for instrumented libs generated by jscoverage/JSCover
+lib-cov
+
+# Coverage directory used by tools like istanbul
+coverage
+
+# nyc test coverage
+.nyc_output
+
+# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
+.grunt
+
+# Bower dependency directory (https://bower.io/)
+bower_components
+
+# node-waf configuration
+.lock-wscript
+
+# Compiled binary addons (https://nodejs.org/api/addons.html)
+build/Release
+
+# Dependency directories
+node_modules/
+jspm_packages/
+
+# Typescript v1 declaration files
+typings/
+
+# Optional npm cache directory
+.npm
+
+# Optional eslint cache
+.eslintcache
+
+# Optional REPL history
+.node_repl_history
+
+# Output of 'npm pack'
+*.tgz
+
+# Yarn Integrity file
+.yarn-integrity
+
+# dotenv environment variables file
+.env
+
+# next.js build output
+.next
diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..ccdd799
--- /dev/null
+++ b/README.md
@@ -0,0 +1,33 @@
+# v[ariant]chess.club
+
+Website to play to many chess variants, including rare ones - some almost never seens
+elsewhere, like "l'Échiqueté" [french], renamed "checkered chess" in english.
+
+## Usage
+
+I hope it's intuitive enough :)
+
+But, a few important points:
+ - All games start with a random assymetric position!
+ - Games are untimed: you decide to play fast or not...
+
+## Resources
+
+Server side:
+ - node + npm packages (see package.json),
+ - pug,
+
+Client side:
+ - Vue.js,
+ - underscore.js
+ - mini.css,
+ - Google font 'Open Sans' + a few icons,
+
+Pieces images where found at various locations.
+
+## Installation (for developers)
+
+ 0. Install git-fat https://github.com/jedbrown/git-fat
+ 1. Rename public/javascripts/utils/socket\_url.js.dist into socket\_url.js and adjust its content.
+ 2. git fat init && git fat pull
+ 3. npm i && npm start
diff --git a/app.js b/app.js
new file mode 100644 (file)
index 0000000..7a8b98f
--- /dev/null
+++ b/app.js
@@ -0,0 +1,61 @@
+var createError = require('http-errors');
+var express = require('express');
+var path = require('path');
+var cookieParser = require('cookie-parser');
+var logger = require('morgan');
+var sassMiddleware = require('node-sass-middleware');
+var favicon = require('serve-favicon');
+
+var router = require('./routes/all');
+
+var app = express();
+
+app.use(favicon(path.join(__dirname, "public", "images", "favicon", "favicon.ico")));
+
+if (app.get('env') === 'development')
+{
+       // Full logging in development mode
+       app.use(logger('dev'));
+}
+else
+{
+       app.set('trust proxy', true); //http://dev.rdybarra.com/2016/06/23/Production-Logging-With-Morgan-In-Express/
+       // In prod, only log error responses (https://github.com/expressjs/morgan)
+       app.use(logger('combined', {
+               skip: function (req, res) { return res.statusCode < 400 }
+       }));
+}
+
+// view engine setup
+app.set('views', path.join(__dirname, 'views'));
+app.set('view engine', 'pug');
+
+app.use(express.json());
+app.use(express.urlencoded({ extended: false }));
+app.use(cookieParser());
+app.use(sassMiddleware({
+  src: path.join(__dirname, 'public'),
+  dest: path.join(__dirname, 'public'),
+  indentedSyntax: true, // true = .sass and false = .scss
+  sourceMap: true
+}));
+app.use(express.static(path.join(__dirname, 'public')));
+
+app.use('/', router);
+
+// catch 404 and forward to error handler
+app.use(function(req, res, next) {
+  next(createError(404));
+});
+
+// error handler
+app.use(function(err, req, res, next) {
+  // set locals, only providing error in development
+  res.locals.message = err.message;
+  res.locals.error = req.app.get('env') === 'development' ? err : {};
+  // render the error page
+  res.status(err.status || 500);
+  res.render('error');
+});
+
+module.exports = app;
diff --git a/bin/www b/bin/www
new file mode 100755 (executable)
index 0000000..e287d50
--- /dev/null
+++ b/bin/www
@@ -0,0 +1,98 @@
+#!/usr/bin/env node
+
+/**
+ * Module dependencies.
+ */
+
+var app = require('../app');
+var debug = require('debug')('vc:server');
+var http = require('http');
+
+/**
+ * Get port from environment and store in Express.
+ */
+
+var port = normalizePort(process.env.PORT || '3000');
+app.set('port', port);
+
+/**
+ * Create HTTP server.
+ */
+
+var server = http.createServer(app);
+
+/**
+ * Listen on provided port, on all network interfaces.
+ */
+
+server.listen(port);
+server.on('error', onError);
+server.on('listening', onListening);
+
+/*
+ * Sockets handling
+ */
+
+const WebSocket = require('ws');
+const wss = new WebSocket.Server({ server: server });
+require('../sockets')(wss);
+
+/**
+ * Normalize a port into a number, string, or false.
+ */
+
+function normalizePort(val) {
+  var port = parseInt(val, 10);
+
+  if (isNaN(port)) {
+    // named pipe
+    return val;
+  }
+
+  if (port >= 0) {
+    // port number
+    return port;
+  }
+
+  return false;
+}
+
+/**
+ * Event listener for HTTP server "error" event.
+ */
+
+function onError(error) {
+  if (error.syscall !== 'listen') {
+    throw error;
+  }
+
+  var bind = typeof port === 'string'
+    ? 'Pipe ' + port
+    : 'Port ' + port;
+
+  // handle specific listen errors with friendly messages
+  switch (error.code) {
+    case 'EACCES':
+      console.error(bind + ' requires elevated privileges');
+      process.exit(1);
+      break;
+    case 'EADDRINUSE':
+      console.error(bind + ' is already in use');
+      process.exit(1);
+      break;
+    default:
+      throw error;
+  }
+}
+
+/**
+ * Event listener for HTTP server "listening" event.
+ */
+
+function onListening() {
+  var addr = server.address();
+  var bind = typeof addr === 'string'
+    ? 'pipe ' + addr
+    : 'port ' + addr.port;
+  debug('Listening on ' + bind);
+}
diff --git a/gulpfile.js b/gulpfile.js
new file mode 100644 (file)
index 0000000..ae739d9
--- /dev/null
@@ -0,0 +1,17 @@
+var gulp = require('gulp');
+var nodemon = require('gulp-nodemon'); //reload server on changes
+
+var nodemonOptions = {
+       script: 'bin/www',
+       ext: 'js',
+       env: { 'NODE_ENV': 'development' },
+       verbose: true,
+       watch: ['./','routes','bin']
+};
+
+gulp.task('start', function () {
+       nodemon(nodemonOptions)
+       .on('restart', function () {
+               console.log('restarted!')
+       });
+});
diff --git a/package-lock.json b/package-lock.json
new file mode 100644 (file)
index 0000000..6a8e44c
--- /dev/null
@@ -0,0 +1,5960 @@
+{
+  "name": "vc",
+  "version": "0.0.0",
+  "lockfileVersion": 1,
+  "requires": true,
+  "dependencies": {
+    "@types/babel-types": {
+      "version": "7.0.4",
+      "resolved": "https://registry.npmjs.org/@types/babel-types/-/babel-types-7.0.4.tgz",
+      "integrity": "sha512-WiZhq3SVJHFRgRYLXvpf65XnV6ipVHhnNaNvE8yCimejrGglkg38kEj0JcizqwSHxmPSjcTlig/6JouxLGEhGw=="
+    },
+    "@types/babylon": {
+      "version": "6.16.4",
+      "resolved": "https://registry.npmjs.org/@types/babylon/-/babylon-6.16.4.tgz",
+      "integrity": "sha512-8dZMcGPno3g7pJ/d0AyJERo+lXh9i1JhDuCUs+4lNIN9eUe5Yh6UCLrpgSEi05Ve2JMLauL2aozdvKwNL0px1Q==",
+      "requires": {
+        "@types/babel-types": "*"
+      }
+    },
+    "abbrev": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+      "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
+    },
+    "accepts": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+      "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+      "requires": {
+        "mime-types": "~2.1.18",
+        "negotiator": "0.6.1"
+      }
+    },
+    "acorn": {
+      "version": "3.3.0",
+      "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
+      "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
+    },
+    "acorn-globals": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
+      "integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
+      "requires": {
+        "acorn": "^4.0.4"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "4.0.13",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+        }
+      }
+    },
+    "ajv": {
+      "version": "6.5.5",
+      "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz",
+      "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==",
+      "requires": {
+        "fast-deep-equal": "^2.0.1",
+        "fast-json-stable-stringify": "^2.0.0",
+        "json-schema-traverse": "^0.4.1",
+        "uri-js": "^4.2.2"
+      }
+    },
+    "align-text": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
+      "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
+      "requires": {
+        "kind-of": "^3.0.2",
+        "longest": "^1.0.1",
+        "repeat-string": "^1.5.2"
+      }
+    },
+    "amdefine": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
+      "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
+    },
+    "ansi-align": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz",
+      "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
+      "dev": true,
+      "requires": {
+        "string-width": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
+      }
+    },
+    "ansi-colors": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/ansi-colors/-/ansi-colors-1.1.0.tgz",
+      "integrity": "sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "^0.1.0"
+      }
+    },
+    "ansi-gray": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
+      "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
+      "dev": true,
+      "requires": {
+        "ansi-wrap": "0.1.0"
+      }
+    },
+    "ansi-regex": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+      "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+    },
+    "ansi-styles": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+      "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
+    },
+    "ansi-wrap": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+      "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
+      "dev": true
+    },
+    "anymatch": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+      "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
+      "dev": true,
+      "requires": {
+        "micromatch": "^3.1.4",
+        "normalize-path": "^2.1.1"
+      }
+    },
+    "append-buffer": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz",
+      "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=",
+      "dev": true,
+      "requires": {
+        "buffer-equal": "^1.0.0"
+      }
+    },
+    "aproba": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz",
+      "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw=="
+    },
+    "archy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz",
+      "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=",
+      "dev": true
+    },
+    "are-we-there-yet": {
+      "version": "1.1.5",
+      "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz",
+      "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==",
+      "requires": {
+        "delegates": "^1.0.0",
+        "readable-stream": "^2.0.6"
+      }
+    },
+    "arr-diff": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+      "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+      "dev": true
+    },
+    "arr-filter": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz",
+      "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "^1.0.0"
+      }
+    },
+    "arr-flatten": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+      "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+      "dev": true
+    },
+    "arr-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz",
+      "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=",
+      "dev": true,
+      "requires": {
+        "make-iterator": "^1.0.0"
+      }
+    },
+    "arr-union": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+      "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+      "dev": true
+    },
+    "array-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz",
+      "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=",
+      "dev": true
+    },
+    "array-find-index": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+      "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
+    },
+    "array-flatten": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+      "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+    },
+    "array-initial": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz",
+      "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=",
+      "dev": true,
+      "requires": {
+        "array-slice": "^1.0.0",
+        "is-number": "^4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "array-last": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz",
+      "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==",
+      "dev": true,
+      "requires": {
+        "is-number": "^4.0.0"
+      },
+      "dependencies": {
+        "is-number": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+          "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+          "dev": true
+        }
+      }
+    },
+    "array-slice": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+      "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
+      "dev": true
+    },
+    "array-sort": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz",
+      "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==",
+      "dev": true,
+      "requires": {
+        "default-compare": "^1.0.0",
+        "get-value": "^2.0.6",
+        "kind-of": "^5.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "array-unique": {
+      "version": "0.3.2",
+      "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+      "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+      "dev": true
+    },
+    "asap": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz",
+      "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
+    },
+    "asn1": {
+      "version": "0.2.4",
+      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+      "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+      "requires": {
+        "safer-buffer": "~2.1.0"
+      }
+    },
+    "assert-plus": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+      "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+    },
+    "assign-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+      "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+      "dev": true
+    },
+    "async-done": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz",
+      "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.2",
+        "process-nextick-args": "^1.0.7",
+        "stream-exhaust": "^1.0.1"
+      },
+      "dependencies": {
+        "process-nextick-args": {
+          "version": "1.0.7",
+          "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
+          "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=",
+          "dev": true
+        }
+      }
+    },
+    "async-each": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz",
+      "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=",
+      "dev": true
+    },
+    "async-foreach": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz",
+      "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI="
+    },
+    "async-limiter": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+      "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
+    },
+    "async-settle": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz",
+      "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=",
+      "dev": true,
+      "requires": {
+        "async-done": "^1.2.2"
+      }
+    },
+    "asynckit": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+      "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+    },
+    "atob": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+      "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+      "dev": true
+    },
+    "aws-sign2": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+      "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+    },
+    "aws4": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+      "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+    },
+    "babel-runtime": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+      "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+      "requires": {
+        "core-js": "^2.4.0",
+        "regenerator-runtime": "^0.11.0"
+      }
+    },
+    "babel-types": {
+      "version": "6.26.0",
+      "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
+      "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
+      "requires": {
+        "babel-runtime": "^6.26.0",
+        "esutils": "^2.0.2",
+        "lodash": "^4.17.4",
+        "to-fast-properties": "^1.0.3"
+      }
+    },
+    "babylon": {
+      "version": "6.18.0",
+      "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz",
+      "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ=="
+    },
+    "bach": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz",
+      "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=",
+      "dev": true,
+      "requires": {
+        "arr-filter": "^1.1.1",
+        "arr-flatten": "^1.0.1",
+        "arr-map": "^2.0.0",
+        "array-each": "^1.0.0",
+        "array-initial": "^1.0.0",
+        "array-last": "^1.1.1",
+        "async-done": "^1.2.2",
+        "async-settle": "^1.0.0",
+        "now-and-later": "^2.0.0"
+      }
+    },
+    "balanced-match": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
+    },
+    "base": {
+      "version": "0.11.2",
+      "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+      "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+      "dev": true,
+      "requires": {
+        "cache-base": "^1.0.1",
+        "class-utils": "^0.3.5",
+        "component-emitter": "^1.2.1",
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.1",
+        "mixin-deep": "^1.2.0",
+        "pascalcase": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "basic-auth": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
+      "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==",
+      "requires": {
+        "safe-buffer": "5.1.2"
+      }
+    },
+    "bcrypt-pbkdf": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+      "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+      "requires": {
+        "tweetnacl": "^0.14.3"
+      }
+    },
+    "binary-extensions": {
+      "version": "1.12.0",
+      "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.12.0.tgz",
+      "integrity": "sha512-DYWGk01lDcxeS/K9IHPGWfT8PsJmbXRtRd2Sx72Tnb8pcYZQFF1oSDb8hJtS1vhp212q1Rzi5dUf9+nq0o9UIg==",
+      "dev": true
+    },
+    "block-stream": {
+      "version": "0.0.9",
+      "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz",
+      "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
+      "requires": {
+        "inherits": "~2.0.0"
+      }
+    },
+    "body-parser": {
+      "version": "1.18.3",
+      "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.3.tgz",
+      "integrity": "sha1-WykhmP/dVTs6DyDe0FkrlWlVyLQ=",
+      "requires": {
+        "bytes": "3.0.0",
+        "content-type": "~1.0.4",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "http-errors": "~1.6.3",
+        "iconv-lite": "0.4.23",
+        "on-finished": "~2.3.0",
+        "qs": "6.5.2",
+        "raw-body": "2.3.3",
+        "type-is": "~1.6.16"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "http-errors": {
+          "version": "1.6.3",
+          "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+          "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.0",
+            "statuses": ">= 1.4.0 < 2"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "boxen": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+      "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
+      "dev": true,
+      "requires": {
+        "ansi-align": "^2.0.0",
+        "camelcase": "^4.0.0",
+        "chalk": "^2.0.1",
+        "cli-boxes": "^1.0.0",
+        "string-width": "^2.0.0",
+        "term-size": "^1.2.0",
+        "widest-line": "^2.0.0"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "camelcase": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+          "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+          "dev": true
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "brace-expansion": {
+      "version": "1.1.11",
+      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+      "requires": {
+        "balanced-match": "^1.0.0",
+        "concat-map": "0.0.1"
+      }
+    },
+    "braces": {
+      "version": "2.3.2",
+      "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+      "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.1.0",
+        "array-unique": "^0.3.2",
+        "extend-shallow": "^2.0.1",
+        "fill-range": "^4.0.0",
+        "isobject": "^3.0.1",
+        "repeat-element": "^1.1.2",
+        "snapdragon": "^0.8.1",
+        "snapdragon-node": "^2.0.1",
+        "split-string": "^3.0.2",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "buffer-equal": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz",
+      "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=",
+      "dev": true
+    },
+    "buffer-from": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+      "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
+      "dev": true
+    },
+    "builtin-modules": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
+      "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8="
+    },
+    "bytes": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
+      "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+    },
+    "cache-base": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+      "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+      "dev": true,
+      "requires": {
+        "collection-visit": "^1.0.0",
+        "component-emitter": "^1.2.1",
+        "get-value": "^2.0.6",
+        "has-value": "^1.0.0",
+        "isobject": "^3.0.1",
+        "set-value": "^2.0.0",
+        "to-object-path": "^0.3.0",
+        "union-value": "^1.0.0",
+        "unset-value": "^1.0.0"
+      }
+    },
+    "camelcase": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+      "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
+    },
+    "camelcase-keys": {
+      "version": "2.1.0",
+      "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+      "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+      "requires": {
+        "camelcase": "^2.0.0",
+        "map-obj": "^1.0.0"
+      }
+    },
+    "capture-stack-trace": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz",
+      "integrity": "sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==",
+      "dev": true
+    },
+    "caseless": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+      "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+    },
+    "center-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
+      "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
+      "requires": {
+        "align-text": "^0.1.3",
+        "lazy-cache": "^1.0.3"
+      }
+    },
+    "chalk": {
+      "version": "1.1.3",
+      "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+      "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+      "requires": {
+        "ansi-styles": "^2.2.1",
+        "escape-string-regexp": "^1.0.2",
+        "has-ansi": "^2.0.0",
+        "strip-ansi": "^3.0.0",
+        "supports-color": "^2.0.0"
+      }
+    },
+    "character-parser": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/character-parser/-/character-parser-2.2.0.tgz",
+      "integrity": "sha1-x84o821LzZdE5f/CxfzeHHMmH8A=",
+      "requires": {
+        "is-regex": "^1.0.3"
+      }
+    },
+    "chokidar": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz",
+      "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==",
+      "dev": true,
+      "requires": {
+        "anymatch": "^2.0.0",
+        "async-each": "^1.0.0",
+        "braces": "^2.3.0",
+        "fsevents": "^1.2.2",
+        "glob-parent": "^3.1.0",
+        "inherits": "^2.0.1",
+        "is-binary-path": "^1.0.0",
+        "is-glob": "^4.0.0",
+        "lodash.debounce": "^4.0.8",
+        "normalize-path": "^2.1.1",
+        "path-is-absolute": "^1.0.0",
+        "readdirp": "^2.0.0",
+        "upath": "^1.0.5"
+      }
+    },
+    "ci-info": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz",
+      "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==",
+      "dev": true
+    },
+    "class-utils": {
+      "version": "0.3.6",
+      "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+      "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "define-property": "^0.2.5",
+        "isobject": "^3.0.0",
+        "static-extend": "^0.1.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "clean-css": {
+      "version": "4.2.1",
+      "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.1.tgz",
+      "integrity": "sha512-4ZxI6dy4lrY6FHzfiy1aEOXgu4LIsW2MhwG0VBKdcoGoH/XLFgaHSdLTGr4O8Be6A8r3MOphEiI8Gc1n0ecf3g==",
+      "requires": {
+        "source-map": "~0.6.0"
+      },
+      "dependencies": {
+        "source-map": {
+          "version": "0.6.1",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+          "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
+        }
+      }
+    },
+    "cli-boxes": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz",
+      "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=",
+      "dev": true
+    },
+    "cliui": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
+      "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
+      "requires": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wrap-ansi": "^2.0.0"
+      }
+    },
+    "clone": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz",
+      "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=",
+      "dev": true
+    },
+    "clone-buffer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz",
+      "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=",
+      "dev": true
+    },
+    "clone-stats": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz",
+      "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=",
+      "dev": true
+    },
+    "cloneable-readable": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.2.tgz",
+      "integrity": "sha512-Bq6+4t+lbM8vhTs/Bef5c5AdEMtapp/iFb6+s4/Hh9MVTt8OLKH7ZOOZSCT+Ys7hsHvqv0GuMPJ1lnQJVHvxpg==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "process-nextick-args": "^2.0.0",
+        "readable-stream": "^2.3.5"
+      }
+    },
+    "code-point-at": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+      "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+    },
+    "collection-map": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz",
+      "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=",
+      "dev": true,
+      "requires": {
+        "arr-map": "^2.0.2",
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
+    "collection-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+      "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+      "dev": true,
+      "requires": {
+        "map-visit": "^1.0.0",
+        "object-visit": "^1.0.0"
+      }
+    },
+    "color-convert": {
+      "version": "1.9.3",
+      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+      "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+      "dev": true,
+      "requires": {
+        "color-name": "1.1.3"
+      }
+    },
+    "color-name": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+      "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+      "dev": true
+    },
+    "color-support": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
+      "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==",
+      "dev": true
+    },
+    "colors": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.2.tgz",
+      "integrity": "sha512-rhP0JSBGYvpcNQj4s5AdShMeE5ahMop96cTeDl/v9qQQm2fYClE2QXZRi8wLzc+GmXSxdIqqbOIAhyObEXDbfQ==",
+      "dev": true
+    },
+    "combined-stream": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
+      "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==",
+      "requires": {
+        "delayed-stream": "~1.0.0"
+      }
+    },
+    "component-emitter": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+      "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=",
+      "dev": true
+    },
+    "concat-map": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
+    },
+    "concat-stream": {
+      "version": "1.6.2",
+      "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+      "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+      "dev": true,
+      "requires": {
+        "buffer-from": "^1.0.0",
+        "inherits": "^2.0.3",
+        "readable-stream": "^2.2.2",
+        "typedarray": "^0.0.6"
+      }
+    },
+    "configstore": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
+      "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
+      "dev": true,
+      "requires": {
+        "dot-prop": "^4.1.0",
+        "graceful-fs": "^4.1.2",
+        "make-dir": "^1.0.0",
+        "unique-string": "^1.0.0",
+        "write-file-atomic": "^2.0.0",
+        "xdg-basedir": "^3.0.0"
+      }
+    },
+    "console-control-strings": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz",
+      "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4="
+    },
+    "constantinople": {
+      "version": "3.1.2",
+      "resolved": "https://registry.npmjs.org/constantinople/-/constantinople-3.1.2.tgz",
+      "integrity": "sha512-yePcBqEFhLOqSBtwYOGGS1exHo/s1xjekXiinh4itpNQGCu4KA1euPh1fg07N2wMITZXQkBz75Ntdt1ctGZouw==",
+      "requires": {
+        "@types/babel-types": "^7.0.0",
+        "@types/babylon": "^6.16.2",
+        "babel-types": "^6.26.0",
+        "babylon": "^6.18.0"
+      }
+    },
+    "content-disposition": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
+      "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+    },
+    "content-type": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
+      "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+    },
+    "convert-source-map": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+      "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+      "dev": true,
+      "requires": {
+        "safe-buffer": "~5.1.1"
+      }
+    },
+    "cookie": {
+      "version": "0.3.1",
+      "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+      "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+    },
+    "cookie-parser": {
+      "version": "1.4.3",
+      "resolved": "https://registry.npmjs.org/cookie-parser/-/cookie-parser-1.4.3.tgz",
+      "integrity": "sha1-D+MfoZ0AC5X0qt8fU/3CuKIDuqU=",
+      "requires": {
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6"
+      }
+    },
+    "cookie-signature": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+      "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+    },
+    "copy-descriptor": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+      "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+      "dev": true
+    },
+    "copy-props": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz",
+      "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==",
+      "dev": true,
+      "requires": {
+        "each-props": "^1.3.0",
+        "is-plain-object": "^2.0.1"
+      }
+    },
+    "core-js": {
+      "version": "2.5.7",
+      "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz",
+      "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw=="
+    },
+    "core-util-is": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+      "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+    },
+    "create-error-class": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz",
+      "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
+      "dev": true,
+      "requires": {
+        "capture-stack-trace": "^1.0.0"
+      }
+    },
+    "cross-spawn": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz",
+      "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=",
+      "requires": {
+        "lru-cache": "^4.0.1",
+        "which": "^1.2.9"
+      }
+    },
+    "crypto-random-string": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz",
+      "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=",
+      "dev": true
+    },
+    "currently-unhandled": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+      "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+      "requires": {
+        "array-find-index": "^1.0.1"
+      }
+    },
+    "d": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz",
+      "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+      "dev": true,
+      "requires": {
+        "es5-ext": "^0.10.9"
+      }
+    },
+    "dashdash": {
+      "version": "1.14.1",
+      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+      "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "debug": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.0.tgz",
+      "integrity": "sha512-heNPJUJIqC+xB6ayLAMHaIrmN9HKa7aQO8MGqKpvCA+uJYVcvR6l5kgdrhRuwPFHU7P5/A1w0BjByPHwpfTDKg==",
+      "requires": {
+        "ms": "^2.1.1"
+      }
+    },
+    "decamelize": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+      "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+    },
+    "decode-uri-component": {
+      "version": "0.2.0",
+      "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+      "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+      "dev": true
+    },
+    "deep-extend": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
+      "dev": true
+    },
+    "default-compare": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz",
+      "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^5.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "default-resolution": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz",
+      "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=",
+      "dev": true
+    },
+    "define-properties": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz",
+      "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==",
+      "dev": true,
+      "requires": {
+        "object-keys": "^1.0.12"
+      }
+    },
+    "define-property": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+      "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+      "dev": true,
+      "requires": {
+        "is-descriptor": "^1.0.2",
+        "isobject": "^3.0.1"
+      },
+      "dependencies": {
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "delayed-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+      "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+    },
+    "delegates": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz",
+      "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
+    },
+    "depd": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+      "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+    },
+    "destroy": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+      "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+    },
+    "detect-file": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+      "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+      "dev": true
+    },
+    "doctypes": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/doctypes/-/doctypes-1.1.0.tgz",
+      "integrity": "sha1-6oCxBqh1OHdOijpKWv4pPeSJ4Kk="
+    },
+    "dot-prop": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+      "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+      "dev": true,
+      "requires": {
+        "is-obj": "^1.0.0"
+      }
+    },
+    "duplexer": {
+      "version": "0.1.1",
+      "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz",
+      "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=",
+      "dev": true
+    },
+    "duplexer3": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz",
+      "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=",
+      "dev": true
+    },
+    "duplexify": {
+      "version": "3.6.1",
+      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.1.tgz",
+      "integrity": "sha512-vM58DwdnKmty+FSPzT14K9JXb90H+j5emaR4KYbr2KTIz00WHGbWOe5ghQTx233ZCLZtrGDALzKwcjEtSt35mA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.0.0",
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.0",
+        "stream-shift": "^1.0.0"
+      }
+    },
+    "each-props": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz",
+      "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==",
+      "dev": true,
+      "requires": {
+        "is-plain-object": "^2.0.1",
+        "object.defaults": "^1.1.0"
+      }
+    },
+    "ecc-jsbn": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+      "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+      "requires": {
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.1.0"
+      }
+    },
+    "ee-first": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+      "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+    },
+    "encodeurl": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+      "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+    },
+    "end-of-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+      "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+      "dev": true,
+      "requires": {
+        "once": "^1.4.0"
+      }
+    },
+    "error-ex": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+      "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+      "requires": {
+        "is-arrayish": "^0.2.1"
+      }
+    },
+    "es5-ext": {
+      "version": "0.10.46",
+      "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.46.tgz",
+      "integrity": "sha512-24XxRvJXNFwEMpJb3nOkiRJKRoupmjYmOPVlI65Qy2SrtxwOTB+g6ODjBKOtwEHbYrhWRty9xxOWLNdClT2djw==",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "~2.0.3",
+        "es6-symbol": "~3.1.1",
+        "next-tick": "1"
+      }
+    },
+    "es6-iterator": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+      "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.35",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "es6-symbol": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
+      "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "~0.10.14"
+      }
+    },
+    "es6-weak-map": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
+      "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
+      "dev": true,
+      "requires": {
+        "d": "1",
+        "es5-ext": "^0.10.14",
+        "es6-iterator": "^2.0.1",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "escape-html": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+      "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+    },
+    "escape-string-regexp": {
+      "version": "1.0.5",
+      "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+      "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
+    },
+    "esutils": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+      "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
+    },
+    "etag": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+      "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+    },
+    "event-stream": {
+      "version": "3.3.6",
+      "resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.6.tgz",
+      "integrity": "sha512-dGXNg4F/FgVzlApjzItL+7naHutA3fDqbV/zAZqDDlXTjiMnQmZKu+prImWKszeBM5UQeGvAl3u1wBiKeDh61g==",
+      "dev": true,
+      "requires": {
+        "duplexer": "^0.1.1",
+        "flatmap-stream": "^0.1.0",
+        "from": "^0.1.7",
+        "map-stream": "0.0.7",
+        "pause-stream": "^0.0.11",
+        "split": "^1.0.1",
+        "stream-combiner": "^0.2.2",
+        "through": "^2.3.8"
+      }
+    },
+    "execa": {
+      "version": "0.7.0",
+      "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+      "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^5.0.1",
+        "get-stream": "^3.0.0",
+        "is-stream": "^1.1.0",
+        "npm-run-path": "^2.0.0",
+        "p-finally": "^1.0.0",
+        "signal-exit": "^3.0.0",
+        "strip-eof": "^1.0.0"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+          "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "shebang-command": "^1.2.0",
+            "which": "^1.2.9"
+          }
+        }
+      }
+    },
+    "expand-brackets": {
+      "version": "2.1.4",
+      "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+      "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.3.3",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "posix-character-classes": "^0.1.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "expand-tilde": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+      "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
+    },
+    "express": {
+      "version": "4.16.4",
+      "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz",
+      "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==",
+      "requires": {
+        "accepts": "~1.3.5",
+        "array-flatten": "1.1.1",
+        "body-parser": "1.18.3",
+        "content-disposition": "0.5.2",
+        "content-type": "~1.0.4",
+        "cookie": "0.3.1",
+        "cookie-signature": "1.0.6",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "finalhandler": "1.1.1",
+        "fresh": "0.5.2",
+        "merge-descriptors": "1.0.1",
+        "methods": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.2",
+        "path-to-regexp": "0.1.7",
+        "proxy-addr": "~2.0.4",
+        "qs": "6.5.2",
+        "range-parser": "~1.2.0",
+        "safe-buffer": "5.1.2",
+        "send": "0.16.2",
+        "serve-static": "1.13.2",
+        "setprototypeof": "1.1.0",
+        "statuses": "~1.4.0",
+        "type-is": "~1.6.16",
+        "utils-merge": "1.0.1",
+        "vary": "~1.1.2"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "extend": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+    },
+    "extend-shallow": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+      "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+      "dev": true,
+      "requires": {
+        "assign-symbols": "^1.0.0",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "extglob": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+      "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+      "dev": true,
+      "requires": {
+        "array-unique": "^0.3.2",
+        "define-property": "^1.0.0",
+        "expand-brackets": "^2.1.4",
+        "extend-shallow": "^2.0.1",
+        "fragment-cache": "^0.2.1",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "extsprintf": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+      "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+    },
+    "fancy-log": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
+      "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
+      "dev": true,
+      "requires": {
+        "ansi-gray": "^0.1.1",
+        "color-support": "^1.1.3",
+        "time-stamp": "^1.0.0"
+      }
+    },
+    "fast-deep-equal": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+      "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
+    },
+    "fast-json-stable-stringify": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+      "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+    },
+    "fill-range": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+      "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1",
+        "to-regex-range": "^2.1.0"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "finalhandler": {
+      "version": "1.1.1",
+      "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+      "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
+      "requires": {
+        "debug": "2.6.9",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "on-finished": "~2.3.0",
+        "parseurl": "~1.3.2",
+        "statuses": "~1.4.0",
+        "unpipe": "~1.0.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "find-up": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+      "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+      "requires": {
+        "path-exists": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      }
+    },
+    "findup-sync": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz",
+      "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=",
+      "dev": true,
+      "requires": {
+        "detect-file": "^1.0.0",
+        "is-glob": "^3.1.0",
+        "micromatch": "^3.0.4",
+        "resolve-dir": "^1.0.1"
+      },
+      "dependencies": {
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.0"
+          }
+        }
+      }
+    },
+    "fined": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz",
+      "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.2",
+        "is-plain-object": "^2.0.3",
+        "object.defaults": "^1.1.0",
+        "object.pick": "^1.2.0",
+        "parse-filepath": "^1.0.1"
+      }
+    },
+    "flagged-respawn": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz",
+      "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=",
+      "dev": true
+    },
+    "flatmap-stream": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/flatmap-stream/-/flatmap-stream-0.1.1.tgz",
+      "integrity": "sha512-lAq4tLbm3sidmdCN8G3ExaxH7cUCtP5mgDvrYowsx84dcYkJJ4I28N7gkxA6+YlSXzaGLJYIDEi9WGfXzMiXdw==",
+      "dev": true
+    },
+    "flush-write-stream": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz",
+      "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==",
+      "dev": true,
+      "requires": {
+        "inherits": "^2.0.1",
+        "readable-stream": "^2.0.4"
+      }
+    },
+    "for-in": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+      "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+      "dev": true
+    },
+    "for-own": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz",
+      "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.1"
+      }
+    },
+    "forever-agent": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+      "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+    },
+    "form-data": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+      "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+      "requires": {
+        "asynckit": "^0.4.0",
+        "combined-stream": "^1.0.6",
+        "mime-types": "^2.1.12"
+      }
+    },
+    "forwarded": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+      "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+    },
+    "fragment-cache": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+      "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+      "dev": true,
+      "requires": {
+        "map-cache": "^0.2.2"
+      }
+    },
+    "fresh": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+      "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+    },
+    "from": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/from/-/from-0.1.7.tgz",
+      "integrity": "sha1-g8YK/Fi5xWmXAH7Rp2izqzA6RP4=",
+      "dev": true
+    },
+    "fs-mkdirp-stream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz",
+      "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "through2": "^2.0.3"
+      }
+    },
+    "fs.realpath": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+      "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+    },
+    "fsevents": {
+      "version": "1.2.4",
+      "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+      "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "^2.9.2",
+        "node-pre-gyp": "^0.10.0"
+      },
+      "dependencies": {
+        "abbrev": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "ansi-regex": {
+          "version": "2.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "aproba": {
+          "version": "1.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "are-we-there-yet": {
+          "version": "1.1.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "delegates": "^1.0.0",
+            "readable-stream": "^2.0.6"
+          }
+        },
+        "balanced-match": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true
+        },
+        "brace-expansion": {
+          "version": "1.1.11",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "balanced-match": "^1.0.0",
+            "concat-map": "0.0.1"
+          }
+        },
+        "chownr": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "code-point-at": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "concat-map": {
+          "version": "0.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "console-control-strings": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true
+        },
+        "core-util-is": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "debug": {
+          "version": "2.6.9",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "deep-extend": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "delegates": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "detect-libc": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "fs-minipass": {
+          "version": "1.2.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "fs.realpath": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "gauge": {
+          "version": "2.7.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "aproba": "^1.0.3",
+            "console-control-strings": "^1.0.0",
+            "has-unicode": "^2.0.0",
+            "object-assign": "^4.1.0",
+            "signal-exit": "^3.0.0",
+            "string-width": "^1.0.1",
+            "strip-ansi": "^3.0.1",
+            "wide-align": "^1.1.0"
+          }
+        },
+        "glob": {
+          "version": "7.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "fs.realpath": "^1.0.0",
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "^3.0.4",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "has-unicode": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "iconv-lite": {
+          "version": "0.4.21",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safer-buffer": "^2.1.0"
+          }
+        },
+        "ignore-walk": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minimatch": "^3.0.4"
+          }
+        },
+        "inflight": {
+          "version": "1.0.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "once": "^1.3.0",
+            "wrappy": "1"
+          }
+        },
+        "inherits": {
+          "version": "2.0.3",
+          "bundled": true,
+          "dev": true
+        },
+        "ini": {
+          "version": "1.3.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "number-is-nan": "^1.0.0"
+          }
+        },
+        "isarray": {
+          "version": "1.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "minimatch": {
+          "version": "3.0.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "brace-expansion": "^1.1.7"
+          }
+        },
+        "minimist": {
+          "version": "0.0.8",
+          "bundled": true,
+          "dev": true
+        },
+        "minipass": {
+          "version": "2.2.4",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "safe-buffer": "^5.1.1",
+            "yallist": "^3.0.0"
+          }
+        },
+        "minizlib": {
+          "version": "1.1.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "minipass": "^2.2.1"
+          }
+        },
+        "mkdirp": {
+          "version": "0.5.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "minimist": "0.0.8"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "needle": {
+          "version": "2.2.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "debug": "^2.1.2",
+            "iconv-lite": "^0.4.4",
+            "sax": "^1.2.4"
+          }
+        },
+        "node-pre-gyp": {
+          "version": "0.10.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "detect-libc": "^1.0.2",
+            "mkdirp": "^0.5.1",
+            "needle": "^2.2.0",
+            "nopt": "^4.0.1",
+            "npm-packlist": "^1.1.6",
+            "npmlog": "^4.0.2",
+            "rc": "^1.1.7",
+            "rimraf": "^2.6.1",
+            "semver": "^5.3.0",
+            "tar": "^4"
+          }
+        },
+        "nopt": {
+          "version": "4.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "abbrev": "1",
+            "osenv": "^0.1.4"
+          }
+        },
+        "npm-bundled": {
+          "version": "1.0.3",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "npm-packlist": {
+          "version": "1.1.10",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "ignore-walk": "^3.0.1",
+            "npm-bundled": "^1.0.1"
+          }
+        },
+        "npmlog": {
+          "version": "4.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "are-we-there-yet": "~1.1.2",
+            "console-control-strings": "~1.1.0",
+            "gauge": "~2.7.3",
+            "set-blocking": "~2.0.0"
+          }
+        },
+        "number-is-nan": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true
+        },
+        "object-assign": {
+          "version": "4.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "once": {
+          "version": "1.4.0",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "wrappy": "1"
+          }
+        },
+        "os-homedir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "os-tmpdir": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "osenv": {
+          "version": "0.1.5",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "os-homedir": "^1.0.0",
+            "os-tmpdir": "^1.0.0"
+          }
+        },
+        "path-is-absolute": {
+          "version": "1.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "process-nextick-args": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "rc": {
+          "version": "1.2.7",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "deep-extend": "^0.5.1",
+            "ini": "~1.3.0",
+            "minimist": "^1.2.0",
+            "strip-json-comments": "~2.0.1"
+          },
+          "dependencies": {
+            "minimist": {
+              "version": "1.2.0",
+              "bundled": true,
+              "dev": true,
+              "optional": true
+            }
+          }
+        },
+        "readable-stream": {
+          "version": "2.3.6",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "core-util-is": "~1.0.0",
+            "inherits": "~2.0.3",
+            "isarray": "~1.0.0",
+            "process-nextick-args": "~2.0.0",
+            "safe-buffer": "~5.1.1",
+            "string_decoder": "~1.1.1",
+            "util-deprecate": "~1.0.1"
+          }
+        },
+        "rimraf": {
+          "version": "2.6.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "^7.0.5"
+          }
+        },
+        "safe-buffer": {
+          "version": "5.1.1",
+          "bundled": true,
+          "dev": true
+        },
+        "safer-buffer": {
+          "version": "2.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "sax": {
+          "version": "1.2.4",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "semver": {
+          "version": "5.5.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "set-blocking": {
+          "version": "2.0.0",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "signal-exit": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "string-width": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "code-point-at": "^1.0.0",
+            "is-fullwidth-code-point": "^1.0.0",
+            "strip-ansi": "^3.0.0"
+          }
+        },
+        "string_decoder": {
+          "version": "1.1.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "safe-buffer": "~5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "3.0.1",
+          "bundled": true,
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^2.0.0"
+          }
+        },
+        "strip-json-comments": {
+          "version": "2.0.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "tar": {
+          "version": "4.4.1",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "chownr": "^1.0.1",
+            "fs-minipass": "^1.2.5",
+            "minipass": "^2.2.4",
+            "minizlib": "^1.1.0",
+            "mkdirp": "^0.5.0",
+            "safe-buffer": "^5.1.1",
+            "yallist": "^3.0.2"
+          }
+        },
+        "util-deprecate": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true
+        },
+        "wide-align": {
+          "version": "1.1.2",
+          "bundled": true,
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "string-width": "^1.0.2"
+          }
+        },
+        "wrappy": {
+          "version": "1.0.2",
+          "bundled": true,
+          "dev": true
+        },
+        "yallist": {
+          "version": "3.0.2",
+          "bundled": true,
+          "dev": true
+        }
+      }
+    },
+    "fstream": {
+      "version": "1.0.11",
+      "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz",
+      "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "inherits": "~2.0.0",
+        "mkdirp": ">=0.5 0",
+        "rimraf": "2"
+      }
+    },
+    "function-bind": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz",
+      "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+    },
+    "gauge": {
+      "version": "2.7.4",
+      "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
+      "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
+      "requires": {
+        "aproba": "^1.0.3",
+        "console-control-strings": "^1.0.0",
+        "has-unicode": "^2.0.0",
+        "object-assign": "^4.1.0",
+        "signal-exit": "^3.0.0",
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1",
+        "wide-align": "^1.1.0"
+      }
+    },
+    "gaze": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+      "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+      "requires": {
+        "globule": "^1.0.0"
+      }
+    },
+    "get-caller-file": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+      "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+    },
+    "get-stdin": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+      "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+    },
+    "get-stream": {
+      "version": "3.0.0",
+      "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+      "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+      "dev": true
+    },
+    "get-value": {
+      "version": "2.0.6",
+      "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+      "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+      "dev": true
+    },
+    "getpass": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
+      "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
+      "requires": {
+        "assert-plus": "^1.0.0"
+      }
+    },
+    "glob": {
+      "version": "7.1.3",
+      "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz",
+      "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==",
+      "requires": {
+        "fs.realpath": "^1.0.0",
+        "inflight": "^1.0.4",
+        "inherits": "2",
+        "minimatch": "^3.0.4",
+        "once": "^1.3.0",
+        "path-is-absolute": "^1.0.0"
+      }
+    },
+    "glob-parent": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+      "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+      "dev": true,
+      "requires": {
+        "is-glob": "^3.1.0",
+        "path-dirname": "^1.0.0"
+      },
+      "dependencies": {
+        "is-glob": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+          "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+          "dev": true,
+          "requires": {
+            "is-extglob": "^2.1.0"
+          }
+        }
+      }
+    },
+    "glob-stream": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz",
+      "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=",
+      "dev": true,
+      "requires": {
+        "extend": "^3.0.0",
+        "glob": "^7.1.1",
+        "glob-parent": "^3.1.0",
+        "is-negated-glob": "^1.0.0",
+        "ordered-read-streams": "^1.0.0",
+        "pumpify": "^1.3.5",
+        "readable-stream": "^2.1.5",
+        "remove-trailing-separator": "^1.0.1",
+        "to-absolute-glob": "^2.0.0",
+        "unique-stream": "^2.0.2"
+      }
+    },
+    "glob-watcher": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.1.tgz",
+      "integrity": "sha512-fK92r2COMC199WCyGUblrZKhjra3cyVMDiypDdqg1vsSDmexnbYivK1kNR4QItiNXLKmGlqan469ks67RtNa2g==",
+      "dev": true,
+      "requires": {
+        "async-done": "^1.2.0",
+        "chokidar": "^2.0.0",
+        "just-debounce": "^1.0.0",
+        "object.defaults": "^1.1.0"
+      }
+    },
+    "global-dirs": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz",
+      "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
+      "dev": true,
+      "requires": {
+        "ini": "^1.3.4"
+      }
+    },
+    "global-modules": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz",
+      "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+      "dev": true,
+      "requires": {
+        "global-prefix": "^1.0.1",
+        "is-windows": "^1.0.1",
+        "resolve-dir": "^1.0.0"
+      }
+    },
+    "global-prefix": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+      "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.2",
+        "homedir-polyfill": "^1.0.1",
+        "ini": "^1.3.4",
+        "is-windows": "^1.0.1",
+        "which": "^1.2.14"
+      }
+    },
+    "globule": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
+      "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
+      "requires": {
+        "glob": "~7.1.1",
+        "lodash": "~4.17.10",
+        "minimatch": "~3.0.2"
+      }
+    },
+    "glogg": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz",
+      "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==",
+      "dev": true,
+      "requires": {
+        "sparkles": "^1.0.0"
+      }
+    },
+    "got": {
+      "version": "6.7.1",
+      "resolved": "http://registry.npmjs.org/got/-/got-6.7.1.tgz",
+      "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
+      "dev": true,
+      "requires": {
+        "create-error-class": "^3.0.0",
+        "duplexer3": "^0.1.4",
+        "get-stream": "^3.0.0",
+        "is-redirect": "^1.0.0",
+        "is-retry-allowed": "^1.0.0",
+        "is-stream": "^1.0.0",
+        "lowercase-keys": "^1.0.0",
+        "safe-buffer": "^5.0.1",
+        "timed-out": "^4.0.0",
+        "unzip-response": "^2.0.1",
+        "url-parse-lax": "^1.0.0"
+      }
+    },
+    "graceful-fs": {
+      "version": "4.1.15",
+      "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+      "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
+    },
+    "gulp": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/gulp/-/gulp-4.0.0.tgz",
+      "integrity": "sha1-lXZsYB2t5Kd+0+eyttwDiBtZY2Y=",
+      "dev": true,
+      "requires": {
+        "glob-watcher": "^5.0.0",
+        "gulp-cli": "^2.0.0",
+        "undertaker": "^1.0.0",
+        "vinyl-fs": "^3.0.0"
+      },
+      "dependencies": {
+        "gulp-cli": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz",
+          "integrity": "sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ==",
+          "dev": true,
+          "requires": {
+            "ansi-colors": "^1.0.1",
+            "archy": "^1.0.0",
+            "array-sort": "^1.0.0",
+            "color-support": "^1.1.3",
+            "concat-stream": "^1.6.0",
+            "copy-props": "^2.0.1",
+            "fancy-log": "^1.3.2",
+            "gulplog": "^1.0.0",
+            "interpret": "^1.1.0",
+            "isobject": "^3.0.1",
+            "liftoff": "^2.5.0",
+            "matchdep": "^2.0.0",
+            "mute-stdout": "^1.0.0",
+            "pretty-hrtime": "^1.0.0",
+            "replace-homedir": "^1.0.0",
+            "semver-greatest-satisfied-range": "^1.1.0",
+            "v8flags": "^3.0.1",
+            "yargs": "^7.1.0"
+          }
+        }
+      }
+    },
+    "gulp-nodemon": {
+      "version": "2.4.1",
+      "resolved": "https://registry.npmjs.org/gulp-nodemon/-/gulp-nodemon-2.4.1.tgz",
+      "integrity": "sha512-IZMEfUZggvXvYDCCbb4jq8xMSsS24OltlgL0KhumhDAbZJUHMm3tHEolHbNLLL9704Wm/DgZ5bdFqCb2hXG0bQ==",
+      "dev": true,
+      "requires": {
+        "colors": "^1.2.1",
+        "event-stream": "^3.3.4",
+        "gulp": "^4.0.0",
+        "nodemon": "^1.17.5"
+      }
+    },
+    "gulplog": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz",
+      "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
+      "dev": true,
+      "requires": {
+        "glogg": "^1.0.0"
+      }
+    },
+    "har-schema": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+      "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+    },
+    "har-validator": {
+      "version": "5.1.3",
+      "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+      "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+      "requires": {
+        "ajv": "^6.5.5",
+        "har-schema": "^2.0.0"
+      }
+    },
+    "has": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz",
+      "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+      "requires": {
+        "function-bind": "^1.1.1"
+      }
+    },
+    "has-ansi": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+      "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "has-flag": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+      "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+      "dev": true
+    },
+    "has-symbols": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz",
+      "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=",
+      "dev": true
+    },
+    "has-unicode": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
+      "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
+    },
+    "has-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+      "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+      "dev": true,
+      "requires": {
+        "get-value": "^2.0.6",
+        "has-values": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "has-values": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+      "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "kind-of": "^4.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+          "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+          "dev": true,
+          "requires": {
+            "is-buffer": "^1.1.5"
+          }
+        }
+      }
+    },
+    "homedir-polyfill": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz",
+      "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
+      "dev": true,
+      "requires": {
+        "parse-passwd": "^1.0.0"
+      }
+    },
+    "hosted-git-info": {
+      "version": "2.7.1",
+      "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+      "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w=="
+    },
+    "http-errors": {
+      "version": "1.7.1",
+      "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.1.tgz",
+      "integrity": "sha512-jWEUgtZWGSMba9I1N3gc1HmvpBUaNC9vDdA46yScAdp+C5rdEuKWUBLWTQpW9FwSWSbYYs++b6SDCxf9UEJzfw==",
+      "requires": {
+        "depd": "~1.1.2",
+        "inherits": "2.0.3",
+        "setprototypeof": "1.1.0",
+        "statuses": ">= 1.5.0 < 2",
+        "toidentifier": "1.0.0"
+      },
+      "dependencies": {
+        "statuses": {
+          "version": "1.5.0",
+          "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+          "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+        }
+      }
+    },
+    "http-signature": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+      "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "jsprim": "^1.2.2",
+        "sshpk": "^1.7.0"
+      }
+    },
+    "iconv-lite": {
+      "version": "0.4.23",
+      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz",
+      "integrity": "sha512-neyTUVFtahjf0mB3dZT77u+8O0QB89jFdnBkd5P1JgYPbPaia3gXXOVL2fq8VyU2gMMD7SaN7QukTB/pmXYvDA==",
+      "requires": {
+        "safer-buffer": ">= 2.1.2 < 3"
+      }
+    },
+    "ignore-by-default": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz",
+      "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=",
+      "dev": true
+    },
+    "import-lazy": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz",
+      "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
+      "dev": true
+    },
+    "imurmurhash": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+      "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+      "dev": true
+    },
+    "in-publish": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz",
+      "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E="
+    },
+    "indent-string": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+      "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+      "requires": {
+        "repeating": "^2.0.0"
+      }
+    },
+    "inflight": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+      "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+      "requires": {
+        "once": "^1.3.0",
+        "wrappy": "1"
+      }
+    },
+    "inherits": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+      "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+    },
+    "ini": {
+      "version": "1.3.5",
+      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+      "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
+      "dev": true
+    },
+    "interpret": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+      "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
+      "dev": true
+    },
+    "invert-kv": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+      "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY="
+    },
+    "ipaddr.js": {
+      "version": "1.8.0",
+      "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz",
+      "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4="
+    },
+    "is-absolute": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz",
+      "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+      "dev": true,
+      "requires": {
+        "is-relative": "^1.0.0",
+        "is-windows": "^1.0.1"
+      }
+    },
+    "is-accessor-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+      "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      }
+    },
+    "is-arrayish": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+      "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+    },
+    "is-binary-path": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz",
+      "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
+      "dev": true,
+      "requires": {
+        "binary-extensions": "^1.0.0"
+      }
+    },
+    "is-buffer": {
+      "version": "1.1.6",
+      "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+      "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w=="
+    },
+    "is-builtin-module": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
+      "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
+      "requires": {
+        "builtin-modules": "^1.0.0"
+      }
+    },
+    "is-ci": {
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz",
+      "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==",
+      "dev": true,
+      "requires": {
+        "ci-info": "^1.5.0"
+      }
+    },
+    "is-data-descriptor": {
+      "version": "0.1.4",
+      "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+      "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      }
+    },
+    "is-descriptor": {
+      "version": "0.1.6",
+      "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+      "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+      "dev": true,
+      "requires": {
+        "is-accessor-descriptor": "^0.1.6",
+        "is-data-descriptor": "^0.1.4",
+        "kind-of": "^5.0.0"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+          "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+          "dev": true
+        }
+      }
+    },
+    "is-expression": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-expression/-/is-expression-3.0.0.tgz",
+      "integrity": "sha1-Oayqa+f9HzRx3ELHQW5hwkMXrJ8=",
+      "requires": {
+        "acorn": "~4.0.2",
+        "object-assign": "^4.0.1"
+      },
+      "dependencies": {
+        "acorn": {
+          "version": "4.0.13",
+          "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz",
+          "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c="
+        }
+      }
+    },
+    "is-extendable": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+      "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+      "dev": true
+    },
+    "is-extglob": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+      "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+      "dev": true
+    },
+    "is-finite": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+      "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "is-fullwidth-code-point": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+      "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+      "requires": {
+        "number-is-nan": "^1.0.0"
+      }
+    },
+    "is-glob": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+      "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+      "dev": true,
+      "requires": {
+        "is-extglob": "^2.1.1"
+      }
+    },
+    "is-installed-globally": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz",
+      "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
+      "dev": true,
+      "requires": {
+        "global-dirs": "^0.1.0",
+        "is-path-inside": "^1.0.0"
+      }
+    },
+    "is-negated-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz",
+      "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=",
+      "dev": true
+    },
+    "is-npm": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz",
+      "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=",
+      "dev": true
+    },
+    "is-number": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+      "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      }
+    },
+    "is-obj": {
+      "version": "1.0.1",
+      "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+      "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+      "dev": true
+    },
+    "is-path-inside": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+      "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
+      "dev": true,
+      "requires": {
+        "path-is-inside": "^1.0.1"
+      }
+    },
+    "is-plain-object": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+      "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "is-promise": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+      "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o="
+    },
+    "is-redirect": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz",
+      "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=",
+      "dev": true
+    },
+    "is-regex": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz",
+      "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
+      "requires": {
+        "has": "^1.0.1"
+      }
+    },
+    "is-relative": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz",
+      "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+      "dev": true,
+      "requires": {
+        "is-unc-path": "^1.0.0"
+      }
+    },
+    "is-retry-allowed": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz",
+      "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=",
+      "dev": true
+    },
+    "is-stream": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+      "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+      "dev": true
+    },
+    "is-typedarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+      "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+    },
+    "is-unc-path": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz",
+      "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+      "dev": true,
+      "requires": {
+        "unc-path-regex": "^0.1.2"
+      }
+    },
+    "is-utf8": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+      "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+    },
+    "is-valid-glob": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz",
+      "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=",
+      "dev": true
+    },
+    "is-windows": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+      "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+      "dev": true
+    },
+    "isarray": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+      "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+    },
+    "isexe": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+      "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
+    },
+    "isobject": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+      "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+      "dev": true
+    },
+    "isstream": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+      "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+    },
+    "js-base64": {
+      "version": "2.4.9",
+      "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.9.tgz",
+      "integrity": "sha512-xcinL3AuDJk7VSzsHgb9DvvIXayBbadtMZ4HFPx8rUszbW1MuNMlwYVC4zzCZ6e1sqZpnNS5ZFYOhXqA39T7LQ=="
+    },
+    "js-stringify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/js-stringify/-/js-stringify-1.0.2.tgz",
+      "integrity": "sha1-Fzb939lyTyijaCrcYjCufk6Weds="
+    },
+    "jsbn": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+      "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+    },
+    "json-schema": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+      "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+    },
+    "json-schema-traverse": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+      "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+    },
+    "json-stable-stringify": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
+      "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
+      "dev": true,
+      "requires": {
+        "jsonify": "~0.0.0"
+      }
+    },
+    "json-stringify-safe": {
+      "version": "5.0.1",
+      "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+      "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+    },
+    "jsonify": {
+      "version": "0.0.0",
+      "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
+      "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=",
+      "dev": true
+    },
+    "jsprim": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+      "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+      "requires": {
+        "assert-plus": "1.0.0",
+        "extsprintf": "1.3.0",
+        "json-schema": "0.2.3",
+        "verror": "1.10.0"
+      }
+    },
+    "jstransformer": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/jstransformer/-/jstransformer-1.0.0.tgz",
+      "integrity": "sha1-7Yvwkh4vPx7U1cGkT2hwntJHIsM=",
+      "requires": {
+        "is-promise": "^2.0.0",
+        "promise": "^7.0.1"
+      }
+    },
+    "just-debounce": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz",
+      "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=",
+      "dev": true
+    },
+    "kind-of": {
+      "version": "3.2.2",
+      "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+      "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+      "requires": {
+        "is-buffer": "^1.1.5"
+      }
+    },
+    "last-run": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz",
+      "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=",
+      "dev": true,
+      "requires": {
+        "default-resolution": "^2.0.0",
+        "es6-weak-map": "^2.0.1"
+      }
+    },
+    "latest-version": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
+      "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
+      "dev": true,
+      "requires": {
+        "package-json": "^4.0.0"
+      }
+    },
+    "lazy-cache": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
+      "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4="
+    },
+    "lazystream": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+      "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.5"
+      }
+    },
+    "lcid": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+      "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+      "requires": {
+        "invert-kv": "^1.0.0"
+      }
+    },
+    "lead": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz",
+      "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=",
+      "dev": true,
+      "requires": {
+        "flush-write-stream": "^1.0.2"
+      }
+    },
+    "liftoff": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz",
+      "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=",
+      "dev": true,
+      "requires": {
+        "extend": "^3.0.0",
+        "findup-sync": "^2.0.0",
+        "fined": "^1.0.1",
+        "flagged-respawn": "^1.0.0",
+        "is-plain-object": "^2.0.4",
+        "object.map": "^1.0.0",
+        "rechoir": "^0.6.2",
+        "resolve": "^1.1.7"
+      }
+    },
+    "load-json-file": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+      "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "parse-json": "^2.2.0",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0",
+        "strip-bom": "^2.0.0"
+      }
+    },
+    "lodash": {
+      "version": "4.17.11",
+      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+      "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+    },
+    "lodash.assign": {
+      "version": "4.2.0",
+      "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
+      "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc="
+    },
+    "lodash.clonedeep": {
+      "version": "4.5.0",
+      "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz",
+      "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8="
+    },
+    "lodash.debounce": {
+      "version": "4.0.8",
+      "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz",
+      "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=",
+      "dev": true
+    },
+    "lodash.mergewith": {
+      "version": "4.6.1",
+      "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz",
+      "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ=="
+    },
+    "longest": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
+      "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
+    },
+    "loud-rejection": {
+      "version": "1.6.0",
+      "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+      "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+      "requires": {
+        "currently-unhandled": "^0.4.1",
+        "signal-exit": "^3.0.0"
+      }
+    },
+    "lowercase-keys": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+      "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
+      "dev": true
+    },
+    "lru-cache": {
+      "version": "4.1.3",
+      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+      "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+      "requires": {
+        "pseudomap": "^1.0.2",
+        "yallist": "^2.1.2"
+      }
+    },
+    "make-dir": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+      "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
+      "dev": true,
+      "requires": {
+        "pify": "^3.0.0"
+      },
+      "dependencies": {
+        "pify": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+          "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+          "dev": true
+        }
+      }
+    },
+    "make-iterator": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz",
+      "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^6.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "map-cache": {
+      "version": "0.2.2",
+      "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+      "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+      "dev": true
+    },
+    "map-obj": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+      "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
+    },
+    "map-stream": {
+      "version": "0.0.7",
+      "resolved": "https://registry.npmjs.org/map-stream/-/map-stream-0.0.7.tgz",
+      "integrity": "sha1-ih8HiW2CsQkmvTdEokIACfiJdKg=",
+      "dev": true
+    },
+    "map-visit": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+      "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+      "dev": true,
+      "requires": {
+        "object-visit": "^1.0.0"
+      }
+    },
+    "matchdep": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz",
+      "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=",
+      "dev": true,
+      "requires": {
+        "findup-sync": "^2.0.0",
+        "micromatch": "^3.0.4",
+        "resolve": "^1.4.0",
+        "stack-trace": "0.0.10"
+      }
+    },
+    "media-typer": {
+      "version": "0.3.0",
+      "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+      "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+    },
+    "meow": {
+      "version": "3.7.0",
+      "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+      "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+      "requires": {
+        "camelcase-keys": "^2.0.0",
+        "decamelize": "^1.1.2",
+        "loud-rejection": "^1.0.0",
+        "map-obj": "^1.0.1",
+        "minimist": "^1.1.3",
+        "normalize-package-data": "^2.3.4",
+        "object-assign": "^4.0.1",
+        "read-pkg-up": "^1.0.1",
+        "redent": "^1.0.0",
+        "trim-newlines": "^1.0.0"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+        }
+      }
+    },
+    "merge-descriptors": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+      "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+    },
+    "methods": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+      "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+    },
+    "micromatch": {
+      "version": "3.1.10",
+      "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+      "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "braces": "^2.3.1",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "extglob": "^2.0.4",
+        "fragment-cache": "^0.2.1",
+        "kind-of": "^6.0.2",
+        "nanomatch": "^1.2.9",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.2"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "mime": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+      "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
+    },
+    "mime-db": {
+      "version": "1.37.0",
+      "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz",
+      "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg=="
+    },
+    "mime-types": {
+      "version": "2.1.21",
+      "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz",
+      "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==",
+      "requires": {
+        "mime-db": "~1.37.0"
+      }
+    },
+    "minimatch": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+      "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+      "requires": {
+        "brace-expansion": "^1.1.7"
+      }
+    },
+    "minimist": {
+      "version": "0.0.8",
+      "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+      "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+    },
+    "mixin-deep": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+      "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+      "dev": true,
+      "requires": {
+        "for-in": "^1.0.2",
+        "is-extendable": "^1.0.1"
+      },
+      "dependencies": {
+        "is-extendable": {
+          "version": "1.0.1",
+          "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+          "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+          "dev": true,
+          "requires": {
+            "is-plain-object": "^2.0.4"
+          }
+        }
+      }
+    },
+    "mkdirp": {
+      "version": "0.5.1",
+      "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+      "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+      "requires": {
+        "minimist": "0.0.8"
+      }
+    },
+    "morgan": {
+      "version": "1.9.1",
+      "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.1.tgz",
+      "integrity": "sha512-HQStPIV4y3afTiCYVxirakhlCfGkI161c76kKFca7Fk1JusM//Qeo1ej2XaMniiNeaZklMVrh3vTtIzpzwbpmA==",
+      "requires": {
+        "basic-auth": "~2.0.0",
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "on-finished": "~2.3.0",
+        "on-headers": "~1.0.1"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "ms": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+      "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+    },
+    "mute-stdout": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz",
+      "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==",
+      "dev": true
+    },
+    "nan": {
+      "version": "2.11.1",
+      "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz",
+      "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA=="
+    },
+    "nanomatch": {
+      "version": "1.2.13",
+      "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+      "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+      "dev": true,
+      "requires": {
+        "arr-diff": "^4.0.0",
+        "array-unique": "^0.3.2",
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "fragment-cache": "^0.2.1",
+        "is-windows": "^1.0.2",
+        "kind-of": "^6.0.2",
+        "object.pick": "^1.3.0",
+        "regex-not": "^1.0.0",
+        "snapdragon": "^0.8.1",
+        "to-regex": "^3.0.1"
+      },
+      "dependencies": {
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "negotiator": {
+      "version": "0.6.1",
+      "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
+      "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+    },
+    "next-tick": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+      "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+      "dev": true
+    },
+    "node-gyp": {
+      "version": "3.8.0",
+      "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz",
+      "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==",
+      "requires": {
+        "fstream": "^1.0.0",
+        "glob": "^7.0.3",
+        "graceful-fs": "^4.1.2",
+        "mkdirp": "^0.5.0",
+        "nopt": "2 || 3",
+        "npmlog": "0 || 1 || 2 || 3 || 4",
+        "osenv": "0",
+        "request": "^2.87.0",
+        "rimraf": "2",
+        "semver": "~5.3.0",
+        "tar": "^2.0.0",
+        "which": "1"
+      },
+      "dependencies": {
+        "semver": {
+          "version": "5.3.0",
+          "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz",
+          "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8="
+        }
+      }
+    },
+    "node-sass": {
+      "version": "4.10.0",
+      "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.10.0.tgz",
+      "integrity": "sha512-fDQJfXszw6vek63Fe/ldkYXmRYK/QS6NbvM3i5oEo9ntPDy4XX7BcKZyTKv+/kSSxRtXXc7l+MSwEmYc0CSy6Q==",
+      "requires": {
+        "async-foreach": "^0.1.3",
+        "chalk": "^1.1.1",
+        "cross-spawn": "^3.0.0",
+        "gaze": "^1.0.0",
+        "get-stdin": "^4.0.1",
+        "glob": "^7.0.3",
+        "in-publish": "^2.0.0",
+        "lodash.assign": "^4.2.0",
+        "lodash.clonedeep": "^4.3.2",
+        "lodash.mergewith": "^4.6.0",
+        "meow": "^3.7.0",
+        "mkdirp": "^0.5.1",
+        "nan": "^2.10.0",
+        "node-gyp": "^3.8.0",
+        "npmlog": "^4.0.0",
+        "request": "^2.88.0",
+        "sass-graph": "^2.2.4",
+        "stdout-stream": "^1.4.0",
+        "true-case-path": "^1.0.2"
+      }
+    },
+    "node-sass-middleware": {
+      "version": "0.11.0",
+      "resolved": "https://registry.npmjs.org/node-sass-middleware/-/node-sass-middleware-0.11.0.tgz",
+      "integrity": "sha1-KrVhJDYpQRAuLNVNihwc70Ra+xU=",
+      "requires": {
+        "mkdirp": "^0.5.1",
+        "node-sass": "^4.3.0"
+      }
+    },
+    "nodemon": {
+      "version": "1.18.6",
+      "resolved": "https://registry.npmjs.org/nodemon/-/nodemon-1.18.6.tgz",
+      "integrity": "sha512-4pHQNYEZun+IkIC2jCaXEhkZnfA7rQe73i8RkdRyDJls/K+WxR7IpI5uNUsAvQ0zWvYcCDNGD+XVtw2ZG86/uQ==",
+      "dev": true,
+      "requires": {
+        "chokidar": "^2.0.4",
+        "debug": "^3.1.0",
+        "ignore-by-default": "^1.0.1",
+        "minimatch": "^3.0.4",
+        "pstree.remy": "^1.1.0",
+        "semver": "^5.5.0",
+        "supports-color": "^5.2.0",
+        "touch": "^3.1.0",
+        "undefsafe": "^2.0.2",
+        "update-notifier": "^2.3.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.2.6",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+          "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "nopt": {
+      "version": "3.0.6",
+      "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+      "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+      "requires": {
+        "abbrev": "1"
+      }
+    },
+    "normalize-package-data": {
+      "version": "2.4.0",
+      "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
+      "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
+      "requires": {
+        "hosted-git-info": "^2.1.4",
+        "is-builtin-module": "^1.0.0",
+        "semver": "2 || 3 || 4 || 5",
+        "validate-npm-package-license": "^3.0.1"
+      }
+    },
+    "normalize-path": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+      "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+      "dev": true,
+      "requires": {
+        "remove-trailing-separator": "^1.0.1"
+      }
+    },
+    "now-and-later": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz",
+      "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=",
+      "dev": true,
+      "requires": {
+        "once": "^1.3.2"
+      }
+    },
+    "npm-run-path": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+      "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+      "dev": true,
+      "requires": {
+        "path-key": "^2.0.0"
+      }
+    },
+    "npmlog": {
+      "version": "4.1.2",
+      "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
+      "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
+      "requires": {
+        "are-we-there-yet": "~1.1.2",
+        "console-control-strings": "~1.1.0",
+        "gauge": "~2.7.3",
+        "set-blocking": "~2.0.0"
+      }
+    },
+    "number-is-nan": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
+      "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
+    },
+    "oauth-sign": {
+      "version": "0.9.0",
+      "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+      "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+    },
+    "object-assign": {
+      "version": "4.1.1",
+      "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+      "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+    },
+    "object-copy": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+      "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+      "dev": true,
+      "requires": {
+        "copy-descriptor": "^0.1.0",
+        "define-property": "^0.2.5",
+        "kind-of": "^3.0.3"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "object-keys": {
+      "version": "1.0.12",
+      "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz",
+      "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==",
+      "dev": true
+    },
+    "object-visit": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+      "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.assign": {
+      "version": "4.1.0",
+      "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz",
+      "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==",
+      "dev": true,
+      "requires": {
+        "define-properties": "^1.1.2",
+        "function-bind": "^1.1.1",
+        "has-symbols": "^1.0.0",
+        "object-keys": "^1.0.11"
+      }
+    },
+    "object.defaults": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz",
+      "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
+      "dev": true,
+      "requires": {
+        "array-each": "^1.0.1",
+        "array-slice": "^1.0.0",
+        "for-own": "^1.0.0",
+        "isobject": "^3.0.0"
+      }
+    },
+    "object.map": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz",
+      "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
+    "object.pick": {
+      "version": "1.3.0",
+      "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+      "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+      "dev": true,
+      "requires": {
+        "isobject": "^3.0.1"
+      }
+    },
+    "object.reduce": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz",
+      "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=",
+      "dev": true,
+      "requires": {
+        "for-own": "^1.0.0",
+        "make-iterator": "^1.0.0"
+      }
+    },
+    "on-finished": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+      "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+      "requires": {
+        "ee-first": "1.1.1"
+      }
+    },
+    "on-headers": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
+      "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+    },
+    "once": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+      "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+      "requires": {
+        "wrappy": "1"
+      }
+    },
+    "ordered-read-streams": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz",
+      "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=",
+      "dev": true,
+      "requires": {
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "os-homedir": {
+      "version": "1.0.2",
+      "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
+      "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
+    },
+    "os-locale": {
+      "version": "1.4.0",
+      "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
+      "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
+      "requires": {
+        "lcid": "^1.0.0"
+      }
+    },
+    "os-tmpdir": {
+      "version": "1.0.2",
+      "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+      "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
+    },
+    "osenv": {
+      "version": "0.1.5",
+      "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+      "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
+      "requires": {
+        "os-homedir": "^1.0.0",
+        "os-tmpdir": "^1.0.0"
+      }
+    },
+    "p-finally": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+      "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+      "dev": true
+    },
+    "package-json": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
+      "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
+      "dev": true,
+      "requires": {
+        "got": "^6.7.1",
+        "registry-auth-token": "^3.0.1",
+        "registry-url": "^3.0.3",
+        "semver": "^5.1.0"
+      }
+    },
+    "parse-filepath": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz",
+      "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=",
+      "dev": true,
+      "requires": {
+        "is-absolute": "^1.0.0",
+        "map-cache": "^0.2.0",
+        "path-root": "^0.1.1"
+      }
+    },
+    "parse-json": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+      "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+      "requires": {
+        "error-ex": "^1.2.0"
+      }
+    },
+    "parse-passwd": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+      "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+      "dev": true
+    },
+    "parseurl": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
+      "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+    },
+    "pascalcase": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+      "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+      "dev": true
+    },
+    "path-dirname": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+      "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+      "dev": true
+    },
+    "path-exists": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+      "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+      "requires": {
+        "pinkie-promise": "^2.0.0"
+      }
+    },
+    "path-is-absolute": {
+      "version": "1.0.1",
+      "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+      "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
+    },
+    "path-is-inside": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+      "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+      "dev": true
+    },
+    "path-key": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+      "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+      "dev": true
+    },
+    "path-parse": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+      "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+    },
+    "path-root": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz",
+      "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
+      "dev": true,
+      "requires": {
+        "path-root-regex": "^0.1.0"
+      }
+    },
+    "path-root-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz",
+      "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=",
+      "dev": true
+    },
+    "path-to-regexp": {
+      "version": "0.1.7",
+      "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
+      "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+    },
+    "path-type": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
+      "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
+      "requires": {
+        "graceful-fs": "^4.1.2",
+        "pify": "^2.0.0",
+        "pinkie-promise": "^2.0.0"
+      }
+    },
+    "pause-stream": {
+      "version": "0.0.11",
+      "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz",
+      "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=",
+      "dev": true,
+      "requires": {
+        "through": "~2.3"
+      }
+    },
+    "performance-now": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+      "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+    },
+    "pify": {
+      "version": "2.3.0",
+      "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
+      "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
+    },
+    "pinkie": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
+      "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
+    },
+    "pinkie-promise": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+      "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
+      "requires": {
+        "pinkie": "^2.0.0"
+      }
+    },
+    "posix-character-classes": {
+      "version": "0.1.1",
+      "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+      "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+      "dev": true
+    },
+    "prepend-http": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz",
+      "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=",
+      "dev": true
+    },
+    "pretty-hrtime": {
+      "version": "1.0.3",
+      "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+      "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
+      "dev": true
+    },
+    "process-nextick-args": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+      "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+    },
+    "promise": {
+      "version": "7.3.1",
+      "resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
+      "integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
+      "requires": {
+        "asap": "~2.0.3"
+      }
+    },
+    "proxy-addr": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz",
+      "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==",
+      "requires": {
+        "forwarded": "~0.1.2",
+        "ipaddr.js": "1.8.0"
+      }
+    },
+    "ps-tree": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/ps-tree/-/ps-tree-1.1.0.tgz",
+      "integrity": "sha1-tCGyQUDWID8e08dplrRCewjowBQ=",
+      "dev": true,
+      "requires": {
+        "event-stream": "~3.3.0"
+      }
+    },
+    "pseudomap": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+      "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
+    },
+    "psl": {
+      "version": "1.1.29",
+      "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz",
+      "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ=="
+    },
+    "pstree.remy": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/pstree.remy/-/pstree.remy-1.1.0.tgz",
+      "integrity": "sha512-q5I5vLRMVtdWa8n/3UEzZX7Lfghzrg9eG2IKk2ENLSofKRCXVqMvMUHxCKgXNaqH/8ebhBxrqftHWnyTFweJ5Q==",
+      "dev": true,
+      "requires": {
+        "ps-tree": "^1.1.0"
+      }
+    },
+    "pug": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/pug/-/pug-2.0.3.tgz",
+      "integrity": "sha1-ccuoJTfJWl6rftBGluQiH1Oqh44=",
+      "requires": {
+        "pug-code-gen": "^2.0.1",
+        "pug-filters": "^3.1.0",
+        "pug-lexer": "^4.0.0",
+        "pug-linker": "^3.0.5",
+        "pug-load": "^2.0.11",
+        "pug-parser": "^5.0.0",
+        "pug-runtime": "^2.0.4",
+        "pug-strip-comments": "^1.0.3"
+      }
+    },
+    "pug-attrs": {
+      "version": "2.0.3",
+      "resolved": "https://registry.npmjs.org/pug-attrs/-/pug-attrs-2.0.3.tgz",
+      "integrity": "sha1-owlflw5kFR972tlX7vVftdeQXRU=",
+      "requires": {
+        "constantinople": "^3.0.1",
+        "js-stringify": "^1.0.1",
+        "pug-runtime": "^2.0.4"
+      }
+    },
+    "pug-code-gen": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pug-code-gen/-/pug-code-gen-2.0.1.tgz",
+      "integrity": "sha1-CVHsgyJddNjPxHan+Zolm199BQw=",
+      "requires": {
+        "constantinople": "^3.0.1",
+        "doctypes": "^1.1.0",
+        "js-stringify": "^1.0.1",
+        "pug-attrs": "^2.0.3",
+        "pug-error": "^1.3.2",
+        "pug-runtime": "^2.0.4",
+        "void-elements": "^2.0.1",
+        "with": "^5.0.0"
+      }
+    },
+    "pug-error": {
+      "version": "1.3.2",
+      "resolved": "https://registry.npmjs.org/pug-error/-/pug-error-1.3.2.tgz",
+      "integrity": "sha1-U659nSm7A89WRJOgJhCfVMR/XyY="
+    },
+    "pug-filters": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/pug-filters/-/pug-filters-3.1.0.tgz",
+      "integrity": "sha1-JxZVVbwEwjbkqisDZiRt+gIbYm4=",
+      "requires": {
+        "clean-css": "^4.1.11",
+        "constantinople": "^3.0.1",
+        "jstransformer": "1.0.0",
+        "pug-error": "^1.3.2",
+        "pug-walk": "^1.1.7",
+        "resolve": "^1.1.6",
+        "uglify-js": "^2.6.1"
+      }
+    },
+    "pug-lexer": {
+      "version": "4.0.0",
+      "resolved": "https://registry.npmjs.org/pug-lexer/-/pug-lexer-4.0.0.tgz",
+      "integrity": "sha1-IQwYRX7y4XYCQnQMXmR715TOwng=",
+      "requires": {
+        "character-parser": "^2.1.1",
+        "is-expression": "^3.0.0",
+        "pug-error": "^1.3.2"
+      }
+    },
+    "pug-linker": {
+      "version": "3.0.5",
+      "resolved": "https://registry.npmjs.org/pug-linker/-/pug-linker-3.0.5.tgz",
+      "integrity": "sha1-npp65ABWgtAn3uuWsAD4juuDoC8=",
+      "requires": {
+        "pug-error": "^1.3.2",
+        "pug-walk": "^1.1.7"
+      }
+    },
+    "pug-load": {
+      "version": "2.0.11",
+      "resolved": "https://registry.npmjs.org/pug-load/-/pug-load-2.0.11.tgz",
+      "integrity": "sha1-5kjlftET/iwfRdV4WOorrWvAFSc=",
+      "requires": {
+        "object-assign": "^4.1.0",
+        "pug-walk": "^1.1.7"
+      }
+    },
+    "pug-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/pug-parser/-/pug-parser-5.0.0.tgz",
+      "integrity": "sha1-45Stmz/KkxI5QK/4hcBuRKt+aOQ=",
+      "requires": {
+        "pug-error": "^1.3.2",
+        "token-stream": "0.0.1"
+      }
+    },
+    "pug-runtime": {
+      "version": "2.0.4",
+      "resolved": "https://registry.npmjs.org/pug-runtime/-/pug-runtime-2.0.4.tgz",
+      "integrity": "sha1-4XjhvaaKsujArPybztLFT9iM61g="
+    },
+    "pug-strip-comments": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/pug-strip-comments/-/pug-strip-comments-1.0.3.tgz",
+      "integrity": "sha1-8VWVkiBu3G+FMQ2s9K+0igJa9Z8=",
+      "requires": {
+        "pug-error": "^1.3.2"
+      }
+    },
+    "pug-walk": {
+      "version": "1.1.7",
+      "resolved": "https://registry.npmjs.org/pug-walk/-/pug-walk-1.1.7.tgz",
+      "integrity": "sha1-wA1cUSi6xYBr7BXSt+fNq+QlMfM="
+    },
+    "pump": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+      "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+      "dev": true,
+      "requires": {
+        "end-of-stream": "^1.1.0",
+        "once": "^1.3.1"
+      }
+    },
+    "pumpify": {
+      "version": "1.5.1",
+      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+      "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
+      "dev": true,
+      "requires": {
+        "duplexify": "^3.6.0",
+        "inherits": "^2.0.3",
+        "pump": "^2.0.0"
+      }
+    },
+    "punycode": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+      "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+    },
+    "qs": {
+      "version": "6.5.2",
+      "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+      "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+    },
+    "range-parser": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
+      "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
+    },
+    "raw-body": {
+      "version": "2.3.3",
+      "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.3.tgz",
+      "integrity": "sha512-9esiElv1BrZoI3rCDuOuKCBRbuApGGaDPQfjSflGxdy4oyzqghxu6klEkkVIvBje+FF0BX9coEv8KqW6X/7njw==",
+      "requires": {
+        "bytes": "3.0.0",
+        "http-errors": "1.6.3",
+        "iconv-lite": "0.4.23",
+        "unpipe": "1.0.0"
+      },
+      "dependencies": {
+        "http-errors": {
+          "version": "1.6.3",
+          "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+          "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.0",
+            "statuses": ">= 1.4.0 < 2"
+          }
+        }
+      }
+    },
+    "rc": {
+      "version": "1.2.8",
+      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+      "dev": true,
+      "requires": {
+        "deep-extend": "^0.6.0",
+        "ini": "~1.3.0",
+        "minimist": "^1.2.0",
+        "strip-json-comments": "~2.0.1"
+      },
+      "dependencies": {
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        }
+      }
+    },
+    "read-pkg": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+      "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+      "requires": {
+        "load-json-file": "^1.0.0",
+        "normalize-package-data": "^2.3.2",
+        "path-type": "^1.0.0"
+      }
+    },
+    "read-pkg-up": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+      "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+      "requires": {
+        "find-up": "^1.0.0",
+        "read-pkg": "^1.0.0"
+      }
+    },
+    "readable-stream": {
+      "version": "2.3.6",
+      "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+      "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+      "requires": {
+        "core-util-is": "~1.0.0",
+        "inherits": "~2.0.3",
+        "isarray": "~1.0.0",
+        "process-nextick-args": "~2.0.0",
+        "safe-buffer": "~5.1.1",
+        "string_decoder": "~1.1.1",
+        "util-deprecate": "~1.0.1"
+      }
+    },
+    "readdirp": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz",
+      "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "micromatch": "^3.1.10",
+        "readable-stream": "^2.0.2"
+      }
+    },
+    "rechoir": {
+      "version": "0.6.2",
+      "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz",
+      "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
+      "dev": true,
+      "requires": {
+        "resolve": "^1.1.6"
+      }
+    },
+    "redent": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+      "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+      "requires": {
+        "indent-string": "^2.1.0",
+        "strip-indent": "^1.0.1"
+      }
+    },
+    "regenerator-runtime": {
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+      "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
+    },
+    "regex-not": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+      "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "registry-auth-token": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+      "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
+      "dev": true,
+      "requires": {
+        "rc": "^1.1.6",
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "registry-url": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz",
+      "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
+      "dev": true,
+      "requires": {
+        "rc": "^1.0.1"
+      }
+    },
+    "remove-bom-buffer": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz",
+      "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==",
+      "dev": true,
+      "requires": {
+        "is-buffer": "^1.1.5",
+        "is-utf8": "^0.2.1"
+      }
+    },
+    "remove-bom-stream": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz",
+      "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=",
+      "dev": true,
+      "requires": {
+        "remove-bom-buffer": "^3.0.0",
+        "safe-buffer": "^5.1.0",
+        "through2": "^2.0.3"
+      }
+    },
+    "remove-trailing-separator": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+      "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+      "dev": true
+    },
+    "repeat-element": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+      "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+      "dev": true
+    },
+    "repeat-string": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+      "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
+    },
+    "repeating": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+      "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+      "requires": {
+        "is-finite": "^1.0.0"
+      }
+    },
+    "replace-ext": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+      "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+      "dev": true
+    },
+    "replace-homedir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz",
+      "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1",
+        "is-absolute": "^1.0.0",
+        "remove-trailing-separator": "^1.1.0"
+      }
+    },
+    "request": {
+      "version": "2.88.0",
+      "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+      "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+      "requires": {
+        "aws-sign2": "~0.7.0",
+        "aws4": "^1.8.0",
+        "caseless": "~0.12.0",
+        "combined-stream": "~1.0.6",
+        "extend": "~3.0.2",
+        "forever-agent": "~0.6.1",
+        "form-data": "~2.3.2",
+        "har-validator": "~5.1.0",
+        "http-signature": "~1.2.0",
+        "is-typedarray": "~1.0.0",
+        "isstream": "~0.1.2",
+        "json-stringify-safe": "~5.0.1",
+        "mime-types": "~2.1.19",
+        "oauth-sign": "~0.9.0",
+        "performance-now": "^2.1.0",
+        "qs": "~6.5.2",
+        "safe-buffer": "^5.1.2",
+        "tough-cookie": "~2.4.3",
+        "tunnel-agent": "^0.6.0",
+        "uuid": "^3.3.2"
+      }
+    },
+    "require-directory": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+      "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I="
+    },
+    "require-main-filename": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+      "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE="
+    },
+    "resolve": {
+      "version": "1.8.1",
+      "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz",
+      "integrity": "sha512-AicPrAC7Qu1JxPCZ9ZgCZlY35QgFnNqc+0LtbRNxnVw4TXvjQ72wnuL9JQcEBgXkI9JM8MsT9kaQoHcpCRJOYA==",
+      "requires": {
+        "path-parse": "^1.0.5"
+      }
+    },
+    "resolve-dir": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz",
+      "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=",
+      "dev": true,
+      "requires": {
+        "expand-tilde": "^2.0.0",
+        "global-modules": "^1.0.0"
+      }
+    },
+    "resolve-options": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz",
+      "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=",
+      "dev": true,
+      "requires": {
+        "value-or-function": "^3.0.0"
+      }
+    },
+    "resolve-url": {
+      "version": "0.2.1",
+      "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+      "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+      "dev": true
+    },
+    "ret": {
+      "version": "0.1.15",
+      "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+      "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+      "dev": true
+    },
+    "right-align": {
+      "version": "0.1.3",
+      "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
+      "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
+      "requires": {
+        "align-text": "^0.1.1"
+      }
+    },
+    "rimraf": {
+      "version": "2.6.2",
+      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+      "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+      "requires": {
+        "glob": "^7.0.5"
+      }
+    },
+    "safe-buffer": {
+      "version": "5.1.2",
+      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+    },
+    "safe-regex": {
+      "version": "1.1.0",
+      "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+      "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+      "dev": true,
+      "requires": {
+        "ret": "~0.1.10"
+      }
+    },
+    "safer-buffer": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+    },
+    "sass-graph": {
+      "version": "2.2.4",
+      "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz",
+      "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=",
+      "requires": {
+        "glob": "^7.0.0",
+        "lodash": "^4.0.0",
+        "scss-tokenizer": "^0.2.3",
+        "yargs": "^7.0.0"
+      }
+    },
+    "scss-tokenizer": {
+      "version": "0.2.3",
+      "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz",
+      "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=",
+      "requires": {
+        "js-base64": "^2.1.8",
+        "source-map": "^0.4.2"
+      }
+    },
+    "semver": {
+      "version": "5.6.0",
+      "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz",
+      "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg=="
+    },
+    "semver-diff": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz",
+      "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
+      "dev": true,
+      "requires": {
+        "semver": "^5.0.3"
+      }
+    },
+    "semver-greatest-satisfied-range": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz",
+      "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=",
+      "dev": true,
+      "requires": {
+        "sver-compat": "^1.5.0"
+      }
+    },
+    "send": {
+      "version": "0.16.2",
+      "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+      "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
+      "requires": {
+        "debug": "2.6.9",
+        "depd": "~1.1.2",
+        "destroy": "~1.0.4",
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "http-errors": "~1.6.2",
+        "mime": "1.4.1",
+        "ms": "2.0.0",
+        "on-finished": "~2.3.0",
+        "range-parser": "~1.2.0",
+        "statuses": "~1.4.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "http-errors": {
+          "version": "1.6.3",
+          "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+          "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+          "requires": {
+            "depd": "~1.1.2",
+            "inherits": "2.0.3",
+            "setprototypeof": "1.1.0",
+            "statuses": ">= 1.4.0 < 2"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+        }
+      }
+    },
+    "serve-favicon": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/serve-favicon/-/serve-favicon-2.5.0.tgz",
+      "integrity": "sha1-k10kDN/g9YBTB/3+ln2IlCosvPA=",
+      "requires": {
+        "etag": "~1.8.1",
+        "fresh": "0.5.2",
+        "ms": "2.1.1",
+        "parseurl": "~1.3.2",
+        "safe-buffer": "5.1.1"
+      },
+      "dependencies": {
+        "safe-buffer": {
+          "version": "5.1.1",
+          "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
+          "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+        }
+      }
+    },
+    "serve-static": {
+      "version": "1.13.2",
+      "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+      "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
+      "requires": {
+        "encodeurl": "~1.0.2",
+        "escape-html": "~1.0.3",
+        "parseurl": "~1.3.2",
+        "send": "0.16.2"
+      }
+    },
+    "set-blocking": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+      "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc="
+    },
+    "set-value": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+      "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^2.0.1",
+        "is-extendable": "^0.1.1",
+        "is-plain-object": "^2.0.3",
+        "split-string": "^3.0.1"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        }
+      }
+    },
+    "setprototypeof": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+      "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
+    },
+    "shebang-command": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+      "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+      "dev": true,
+      "requires": {
+        "shebang-regex": "^1.0.0"
+      }
+    },
+    "shebang-regex": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+      "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+      "dev": true
+    },
+    "signal-exit": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+      "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+    },
+    "snapdragon": {
+      "version": "0.8.2",
+      "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+      "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+      "dev": true,
+      "requires": {
+        "base": "^0.11.1",
+        "debug": "^2.2.0",
+        "define-property": "^0.2.5",
+        "extend-shallow": "^2.0.1",
+        "map-cache": "^0.2.2",
+        "source-map": "^0.5.6",
+        "source-map-resolve": "^0.5.0",
+        "use": "^3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        },
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-node": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+      "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^1.0.0",
+        "isobject": "^3.0.0",
+        "snapdragon-util": "^3.0.1"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+          "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^1.0.0"
+          }
+        },
+        "is-accessor-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+          "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-data-descriptor": {
+          "version": "1.0.0",
+          "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+          "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+          "dev": true,
+          "requires": {
+            "kind-of": "^6.0.0"
+          }
+        },
+        "is-descriptor": {
+          "version": "1.0.2",
+          "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+          "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+          "dev": true,
+          "requires": {
+            "is-accessor-descriptor": "^1.0.0",
+            "is-data-descriptor": "^1.0.0",
+            "kind-of": "^6.0.2"
+          }
+        },
+        "kind-of": {
+          "version": "6.0.2",
+          "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+          "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+          "dev": true
+        }
+      }
+    },
+    "snapdragon-util": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+      "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.2.0"
+      }
+    },
+    "source-map": {
+      "version": "0.4.4",
+      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+      "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+      "requires": {
+        "amdefine": ">=0.0.4"
+      }
+    },
+    "source-map-resolve": {
+      "version": "0.5.2",
+      "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+      "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+      "dev": true,
+      "requires": {
+        "atob": "^2.1.1",
+        "decode-uri-component": "^0.2.0",
+        "resolve-url": "^0.2.1",
+        "source-map-url": "^0.4.0",
+        "urix": "^0.1.0"
+      }
+    },
+    "source-map-url": {
+      "version": "0.4.0",
+      "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+      "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+      "dev": true
+    },
+    "sparkles": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+      "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
+      "dev": true
+    },
+    "spdx-correct": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz",
+      "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==",
+      "requires": {
+        "spdx-expression-parse": "^3.0.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-exceptions": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+      "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
+    },
+    "spdx-expression-parse": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+      "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+      "requires": {
+        "spdx-exceptions": "^2.1.0",
+        "spdx-license-ids": "^3.0.0"
+      }
+    },
+    "spdx-license-ids": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz",
+      "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg=="
+    },
+    "split": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+      "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+      "dev": true,
+      "requires": {
+        "through": "2"
+      }
+    },
+    "split-string": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+      "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+      "dev": true,
+      "requires": {
+        "extend-shallow": "^3.0.0"
+      }
+    },
+    "sshpk": {
+      "version": "1.15.2",
+      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz",
+      "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==",
+      "requires": {
+        "asn1": "~0.2.3",
+        "assert-plus": "^1.0.0",
+        "bcrypt-pbkdf": "^1.0.0",
+        "dashdash": "^1.12.0",
+        "ecc-jsbn": "~0.1.1",
+        "getpass": "^0.1.1",
+        "jsbn": "~0.1.0",
+        "safer-buffer": "^2.0.2",
+        "tweetnacl": "~0.14.0"
+      }
+    },
+    "stack-trace": {
+      "version": "0.0.10",
+      "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz",
+      "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=",
+      "dev": true
+    },
+    "static-extend": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+      "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+      "dev": true,
+      "requires": {
+        "define-property": "^0.2.5",
+        "object-copy": "^0.1.0"
+      },
+      "dependencies": {
+        "define-property": {
+          "version": "0.2.5",
+          "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+          "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+          "dev": true,
+          "requires": {
+            "is-descriptor": "^0.1.0"
+          }
+        }
+      }
+    },
+    "statuses": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+      "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew=="
+    },
+    "stdout-stream": {
+      "version": "1.4.1",
+      "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.1.tgz",
+      "integrity": "sha512-j4emi03KXqJWcIeF8eIXkjMFN1Cmb8gUlDYGeBALLPo5qdyTfA9bOtl8m33lRoC+vFMkP3gl0WsDr6+gzxbbTA==",
+      "requires": {
+        "readable-stream": "^2.0.1"
+      }
+    },
+    "stream-combiner": {
+      "version": "0.2.2",
+      "resolved": "http://registry.npmjs.org/stream-combiner/-/stream-combiner-0.2.2.tgz",
+      "integrity": "sha1-rsjLrBd7Vrb0+kec7YwZEs7lKFg=",
+      "dev": true,
+      "requires": {
+        "duplexer": "~0.1.1",
+        "through": "~2.3.4"
+      }
+    },
+    "stream-exhaust": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz",
+      "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==",
+      "dev": true
+    },
+    "stream-shift": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
+      "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=",
+      "dev": true
+    },
+    "string-width": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
+      "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
+      "requires": {
+        "code-point-at": "^1.0.0",
+        "is-fullwidth-code-point": "^1.0.0",
+        "strip-ansi": "^3.0.0"
+      }
+    },
+    "string_decoder": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+      "requires": {
+        "safe-buffer": "~5.1.0"
+      }
+    },
+    "strip-ansi": {
+      "version": "3.0.1",
+      "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
+      "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
+      "requires": {
+        "ansi-regex": "^2.0.0"
+      }
+    },
+    "strip-bom": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+      "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+      "requires": {
+        "is-utf8": "^0.2.0"
+      }
+    },
+    "strip-eof": {
+      "version": "1.0.0",
+      "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+      "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+      "dev": true
+    },
+    "strip-indent": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+      "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+      "requires": {
+        "get-stdin": "^4.0.1"
+      }
+    },
+    "strip-json-comments": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+      "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=",
+      "dev": true
+    },
+    "supports-color": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+      "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
+    },
+    "sver-compat": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz",
+      "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=",
+      "dev": true,
+      "requires": {
+        "es6-iterator": "^2.0.1",
+        "es6-symbol": "^3.1.1"
+      }
+    },
+    "tar": {
+      "version": "2.2.1",
+      "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz",
+      "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
+      "requires": {
+        "block-stream": "*",
+        "fstream": "^1.0.2",
+        "inherits": "2"
+      }
+    },
+    "term-size": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz",
+      "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
+      "dev": true,
+      "requires": {
+        "execa": "^0.7.0"
+      }
+    },
+    "through": {
+      "version": "2.3.8",
+      "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz",
+      "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+      "dev": true
+    },
+    "through2": {
+      "version": "2.0.5",
+      "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz",
+      "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==",
+      "dev": true,
+      "requires": {
+        "readable-stream": "~2.3.6",
+        "xtend": "~4.0.1"
+      }
+    },
+    "through2-filter": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz",
+      "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
+      "dev": true,
+      "requires": {
+        "through2": "~2.0.0",
+        "xtend": "~4.0.0"
+      }
+    },
+    "time-stamp": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz",
+      "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=",
+      "dev": true
+    },
+    "timed-out": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz",
+      "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=",
+      "dev": true
+    },
+    "to-absolute-glob": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz",
+      "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=",
+      "dev": true,
+      "requires": {
+        "is-absolute": "^1.0.0",
+        "is-negated-glob": "^1.0.0"
+      }
+    },
+    "to-fast-properties": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz",
+      "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc="
+    },
+    "to-object-path": {
+      "version": "0.3.0",
+      "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+      "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+      "dev": true,
+      "requires": {
+        "kind-of": "^3.0.2"
+      }
+    },
+    "to-regex": {
+      "version": "3.0.2",
+      "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+      "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+      "dev": true,
+      "requires": {
+        "define-property": "^2.0.2",
+        "extend-shallow": "^3.0.2",
+        "regex-not": "^1.0.2",
+        "safe-regex": "^1.1.0"
+      }
+    },
+    "to-regex-range": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+      "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+      "dev": true,
+      "requires": {
+        "is-number": "^3.0.0",
+        "repeat-string": "^1.6.1"
+      }
+    },
+    "to-through": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz",
+      "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=",
+      "dev": true,
+      "requires": {
+        "through2": "^2.0.3"
+      }
+    },
+    "toidentifier": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+      "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+    },
+    "token-stream": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/token-stream/-/token-stream-0.0.1.tgz",
+      "integrity": "sha1-zu78cXp2xDFvEm0LnbqlXX598Bo="
+    },
+    "touch": {
+      "version": "3.1.0",
+      "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz",
+      "integrity": "sha512-WBx8Uy5TLtOSRtIq+M03/sKDrXCLHxwDcquSP2c43Le03/9serjQBIztjRz6FkJez9D/hleyAXTBGLwwZUw9lA==",
+      "dev": true,
+      "requires": {
+        "nopt": "~1.0.10"
+      },
+      "dependencies": {
+        "nopt": {
+          "version": "1.0.10",
+          "resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
+          "integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
+          "dev": true,
+          "requires": {
+            "abbrev": "1"
+          }
+        }
+      }
+    },
+    "tough-cookie": {
+      "version": "2.4.3",
+      "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+      "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+      "requires": {
+        "psl": "^1.1.24",
+        "punycode": "^1.4.1"
+      },
+      "dependencies": {
+        "punycode": {
+          "version": "1.4.1",
+          "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+          "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+        }
+      }
+    },
+    "trim-newlines": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+      "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
+    },
+    "true-case-path": {
+      "version": "1.0.3",
+      "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.3.tgz",
+      "integrity": "sha512-m6s2OdQe5wgpFMC+pAJ+q9djG82O2jcHPOI6RNg1yy9rCYR+WD6Nbpl32fDpfC56nirdRy+opFa/Vk7HYhqaew==",
+      "requires": {
+        "glob": "^7.1.2"
+      }
+    },
+    "tunnel-agent": {
+      "version": "0.6.0",
+      "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+      "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+      "requires": {
+        "safe-buffer": "^5.0.1"
+      }
+    },
+    "tweetnacl": {
+      "version": "0.14.5",
+      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+      "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+    },
+    "type-is": {
+      "version": "1.6.16",
+      "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+      "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+      "requires": {
+        "media-typer": "0.3.0",
+        "mime-types": "~2.1.18"
+      }
+    },
+    "typedarray": {
+      "version": "0.0.6",
+      "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+      "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=",
+      "dev": true
+    },
+    "uglify-js": {
+      "version": "2.8.29",
+      "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
+      "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
+      "requires": {
+        "source-map": "~0.5.1",
+        "uglify-to-browserify": "~1.0.0",
+        "yargs": "~3.10.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "1.2.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
+          "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk="
+        },
+        "cliui": {
+          "version": "2.1.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
+          "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
+          "requires": {
+            "center-align": "^0.1.1",
+            "right-align": "^0.1.1",
+            "wordwrap": "0.0.2"
+          }
+        },
+        "source-map": {
+          "version": "0.5.7",
+          "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+          "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+        },
+        "yargs": {
+          "version": "3.10.0",
+          "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
+          "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
+          "requires": {
+            "camelcase": "^1.0.2",
+            "cliui": "^2.1.0",
+            "decamelize": "^1.0.0",
+            "window-size": "0.1.0"
+          }
+        }
+      }
+    },
+    "uglify-to-browserify": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
+      "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
+      "optional": true
+    },
+    "unc-path-regex": {
+      "version": "0.1.2",
+      "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+      "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=",
+      "dev": true
+    },
+    "undefsafe": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz",
+      "integrity": "sha1-Il9rngM3Zj4Njnz9aG/Cg2zKznY=",
+      "dev": true,
+      "requires": {
+        "debug": "^2.2.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "2.6.9",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+          "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+          "dev": true,
+          "requires": {
+            "ms": "2.0.0"
+          }
+        },
+        "ms": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+          "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+          "dev": true
+        }
+      }
+    },
+    "undertaker": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz",
+      "integrity": "sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=",
+      "dev": true,
+      "requires": {
+        "arr-flatten": "^1.0.1",
+        "arr-map": "^2.0.0",
+        "bach": "^1.0.0",
+        "collection-map": "^1.0.0",
+        "es6-weak-map": "^2.0.1",
+        "last-run": "^1.1.0",
+        "object.defaults": "^1.0.0",
+        "object.reduce": "^1.0.0",
+        "undertaker-registry": "^1.0.0"
+      }
+    },
+    "undertaker-registry": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz",
+      "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=",
+      "dev": true
+    },
+    "union-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+      "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+      "dev": true,
+      "requires": {
+        "arr-union": "^3.1.0",
+        "get-value": "^2.0.6",
+        "is-extendable": "^0.1.1",
+        "set-value": "^0.4.3"
+      },
+      "dependencies": {
+        "extend-shallow": {
+          "version": "2.0.1",
+          "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+          "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+          "dev": true,
+          "requires": {
+            "is-extendable": "^0.1.0"
+          }
+        },
+        "set-value": {
+          "version": "0.4.3",
+          "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+          "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+          "dev": true,
+          "requires": {
+            "extend-shallow": "^2.0.1",
+            "is-extendable": "^0.1.1",
+            "is-plain-object": "^2.0.1",
+            "to-object-path": "^0.3.0"
+          }
+        }
+      }
+    },
+    "unique-stream": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz",
+      "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=",
+      "dev": true,
+      "requires": {
+        "json-stable-stringify": "^1.0.0",
+        "through2-filter": "^2.0.0"
+      }
+    },
+    "unique-string": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz",
+      "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
+      "dev": true,
+      "requires": {
+        "crypto-random-string": "^1.0.0"
+      }
+    },
+    "unpipe": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+      "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+    },
+    "unset-value": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+      "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+      "dev": true,
+      "requires": {
+        "has-value": "^0.3.1",
+        "isobject": "^3.0.0"
+      },
+      "dependencies": {
+        "has-value": {
+          "version": "0.3.1",
+          "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+          "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+          "dev": true,
+          "requires": {
+            "get-value": "^2.0.3",
+            "has-values": "^0.1.4",
+            "isobject": "^2.0.0"
+          },
+          "dependencies": {
+            "isobject": {
+              "version": "2.1.0",
+              "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+              "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+              "dev": true,
+              "requires": {
+                "isarray": "1.0.0"
+              }
+            }
+          }
+        },
+        "has-values": {
+          "version": "0.1.4",
+          "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+          "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+          "dev": true
+        }
+      }
+    },
+    "unzip-response": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+      "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
+      "dev": true
+    },
+    "upath": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
+      "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+      "dev": true
+    },
+    "update-notifier": {
+      "version": "2.5.0",
+      "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
+      "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
+      "dev": true,
+      "requires": {
+        "boxen": "^1.2.1",
+        "chalk": "^2.0.1",
+        "configstore": "^3.0.0",
+        "import-lazy": "^2.1.0",
+        "is-ci": "^1.0.10",
+        "is-installed-globally": "^0.1.0",
+        "is-npm": "^1.0.0",
+        "latest-version": "^3.0.0",
+        "semver-diff": "^2.0.0",
+        "xdg-basedir": "^3.0.0"
+      },
+      "dependencies": {
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "chalk": {
+          "version": "2.4.1",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+          "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        }
+      }
+    },
+    "uri-js": {
+      "version": "4.2.2",
+      "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+      "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+      "requires": {
+        "punycode": "^2.1.0"
+      }
+    },
+    "urix": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+      "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+      "dev": true
+    },
+    "url-parse-lax": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz",
+      "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
+      "dev": true,
+      "requires": {
+        "prepend-http": "^1.0.1"
+      }
+    },
+    "use": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+      "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+      "dev": true
+    },
+    "util-deprecate": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+      "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+    },
+    "utils-merge": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+      "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+    },
+    "uuid": {
+      "version": "3.3.2",
+      "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+      "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+    },
+    "v8flags": {
+      "version": "3.1.1",
+      "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz",
+      "integrity": "sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==",
+      "dev": true,
+      "requires": {
+        "homedir-polyfill": "^1.0.1"
+      }
+    },
+    "validate-npm-package-license": {
+      "version": "3.0.4",
+      "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+      "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+      "requires": {
+        "spdx-correct": "^3.0.0",
+        "spdx-expression-parse": "^3.0.0"
+      }
+    },
+    "value-or-function": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz",
+      "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=",
+      "dev": true
+    },
+    "vary": {
+      "version": "1.1.2",
+      "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+      "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+    },
+    "verror": {
+      "version": "1.10.0",
+      "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+      "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+      "requires": {
+        "assert-plus": "^1.0.0",
+        "core-util-is": "1.0.2",
+        "extsprintf": "^1.2.0"
+      }
+    },
+    "vinyl": {
+      "version": "2.2.0",
+      "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.0.tgz",
+      "integrity": "sha512-MBH+yP0kC/GQ5GwBqrTPTzEfiiLjta7hTtvQtbxBgTeSXsmKQRQecjibMbxIXzVT3Y9KJK+drOz1/k+vsu8Nkg==",
+      "dev": true,
+      "requires": {
+        "clone": "^2.1.1",
+        "clone-buffer": "^1.0.0",
+        "clone-stats": "^1.0.0",
+        "cloneable-readable": "^1.0.0",
+        "remove-trailing-separator": "^1.0.1",
+        "replace-ext": "^1.0.0"
+      }
+    },
+    "vinyl-fs": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz",
+      "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==",
+      "dev": true,
+      "requires": {
+        "fs-mkdirp-stream": "^1.0.0",
+        "glob-stream": "^6.1.0",
+        "graceful-fs": "^4.0.0",
+        "is-valid-glob": "^1.0.0",
+        "lazystream": "^1.0.0",
+        "lead": "^1.0.0",
+        "object.assign": "^4.0.4",
+        "pumpify": "^1.3.5",
+        "readable-stream": "^2.3.3",
+        "remove-bom-buffer": "^3.0.0",
+        "remove-bom-stream": "^1.2.0",
+        "resolve-options": "^1.1.0",
+        "through2": "^2.0.0",
+        "to-through": "^2.0.0",
+        "value-or-function": "^3.0.0",
+        "vinyl": "^2.0.0",
+        "vinyl-sourcemap": "^1.1.0"
+      }
+    },
+    "vinyl-sourcemap": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz",
+      "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=",
+      "dev": true,
+      "requires": {
+        "append-buffer": "^1.0.2",
+        "convert-source-map": "^1.5.0",
+        "graceful-fs": "^4.1.6",
+        "normalize-path": "^2.1.1",
+        "now-and-later": "^2.0.0",
+        "remove-bom-buffer": "^3.0.0",
+        "vinyl": "^2.0.0"
+      }
+    },
+    "void-elements": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-2.0.1.tgz",
+      "integrity": "sha1-wGavtYK7HLQSjWDqkjkulNXp2+w="
+    },
+    "which": {
+      "version": "1.3.1",
+      "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+      "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+      "requires": {
+        "isexe": "^2.0.0"
+      }
+    },
+    "which-module": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
+      "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
+    },
+    "wide-align": {
+      "version": "1.1.3",
+      "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz",
+      "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==",
+      "requires": {
+        "string-width": "^1.0.2 || 2"
+      }
+    },
+    "widest-line": {
+      "version": "2.0.1",
+      "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz",
+      "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==",
+      "dev": true,
+      "requires": {
+        "string-width": "^2.1.1"
+      },
+      "dependencies": {
+        "ansi-regex": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+          "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "string-width": {
+          "version": "2.1.1",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+          "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+          "dev": true,
+          "requires": {
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^4.0.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+          "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^3.0.0"
+          }
+        }
+      }
+    },
+    "window-size": {
+      "version": "0.1.0",
+      "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
+      "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0="
+    },
+    "with": {
+      "version": "5.1.1",
+      "resolved": "https://registry.npmjs.org/with/-/with-5.1.1.tgz",
+      "integrity": "sha1-+k2qktrzLE6pTtRTyB8EaGtXXf4=",
+      "requires": {
+        "acorn": "^3.1.0",
+        "acorn-globals": "^3.0.0"
+      }
+    },
+    "wordwrap": {
+      "version": "0.0.2",
+      "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
+      "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8="
+    },
+    "wrap-ansi": {
+      "version": "2.1.0",
+      "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+      "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+      "requires": {
+        "string-width": "^1.0.1",
+        "strip-ansi": "^3.0.1"
+      }
+    },
+    "wrappy": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+      "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
+    },
+    "write-file-atomic": {
+      "version": "2.3.0",
+      "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz",
+      "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "imurmurhash": "^0.1.4",
+        "signal-exit": "^3.0.2"
+      }
+    },
+    "ws": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.0.tgz",
+      "integrity": "sha512-H3dGVdGvW2H8bnYpIDc3u3LH8Wue3Qh+Zto6aXXFzvESkTVT6rAfKR6tR/+coaUvxs8yHtmNV0uioBF62ZGSTg==",
+      "requires": {
+        "async-limiter": "~1.0.0"
+      }
+    },
+    "xdg-basedir": {
+      "version": "3.0.0",
+      "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz",
+      "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=",
+      "dev": true
+    },
+    "xtend": {
+      "version": "4.0.1",
+      "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+      "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+      "dev": true
+    },
+    "y18n": {
+      "version": "3.2.1",
+      "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+      "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE="
+    },
+    "yallist": {
+      "version": "2.1.2",
+      "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+      "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
+    },
+    "yargs": {
+      "version": "7.1.0",
+      "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+      "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+      "requires": {
+        "camelcase": "^3.0.0",
+        "cliui": "^3.2.0",
+        "decamelize": "^1.1.1",
+        "get-caller-file": "^1.0.1",
+        "os-locale": "^1.4.0",
+        "read-pkg-up": "^1.0.1",
+        "require-directory": "^2.1.1",
+        "require-main-filename": "^1.0.1",
+        "set-blocking": "^2.0.0",
+        "string-width": "^1.0.2",
+        "which-module": "^1.0.0",
+        "y18n": "^3.2.1",
+        "yargs-parser": "^5.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+        }
+      }
+    },
+    "yargs-parser": {
+      "version": "5.0.0",
+      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz",
+      "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
+      "requires": {
+        "camelcase": "^3.0.0"
+      },
+      "dependencies": {
+        "camelcase": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+          "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+        }
+      }
+    }
+  }
+}
diff --git a/package.json b/package.json
new file mode 100644 (file)
index 0000000..ee95dd5
--- /dev/null
@@ -0,0 +1,22 @@
+{
+  "name": "vc",
+  "version": "0.0.0",
+  "private": true,
+  "scripts": {
+    "start": "gulp start"
+  },
+  "dependencies": {
+    "cookie-parser": "~1.4.3",
+    "debug": "~4.1.0",
+    "express": "~4.16.4",
+    "http-errors": "~1.7.1",
+    "morgan": "~1.9.1",
+    "node-sass-middleware": "~0.11.0",
+    "pug": "~2.0.3",
+    "serve-favicon": "~2.5.0",
+    "ws": "~6.1.0"
+  },
+  "devDependencies": {
+    "gulp-nodemon": "~2.4.1"
+  }
+}
diff --git a/public/images/favicon/README b/public/images/favicon/README
new file mode 100644 (file)
index 0000000..7d25d19
--- /dev/null
@@ -0,0 +1,3 @@
+Generated using https://realfavicongenerator.net/ ,
+with an image from here:
+https://www.freefavicon.com/freefavicons/objects/iconinfo/chess-piece-silhouette---red-king--rey-rojo-152-275290.html
diff --git a/public/images/favicon/android-chrome-192x192.png b/public/images/favicon/android-chrome-192x192.png
new file mode 100644 (file)
index 0000000..727630a
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 9249f7ccb03573152b1210b27c244462ac286aea                12108
diff --git a/public/images/favicon/android-chrome-512x512.png b/public/images/favicon/android-chrome-512x512.png
new file mode 100644 (file)
index 0000000..bd462bb
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 510e77fc0cd116eb8ef2e8743718f4c1c22393ec                33049
diff --git a/public/images/favicon/apple-touch-icon.png b/public/images/favicon/apple-touch-icon.png
new file mode 100644 (file)
index 0000000..1b453ab
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 60b73e04ab8fc7a125745cbdc8f6f5cb298c105f                12621
diff --git a/public/images/favicon/browserconfig.xml b/public/images/favicon/browserconfig.xml
new file mode 100644 (file)
index 0000000..bb8e477
--- /dev/null
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<browserconfig>
+    <msapplication>
+        <tile>
+                                       <square150x150logo src="/images/favicon/mstile-150x150.png"/>
+            <TileColor>#da532c</TileColor>
+        </tile>
+    </msapplication>
+</browserconfig>
diff --git a/public/images/favicon/favicon-16x16.png b/public/images/favicon/favicon-16x16.png
new file mode 100644 (file)
index 0000000..b334454
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 10c5fd36c2cb305a3f7e6a6f39eccba03a679087                  995
diff --git a/public/images/favicon/favicon-32x32.png b/public/images/favicon/favicon-32x32.png
new file mode 100644 (file)
index 0000000..386456d
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 53091595a131897b202391f3f0ffaa61f283c56a                 1877
diff --git a/public/images/favicon/favicon.ico b/public/images/favicon/favicon.ico
new file mode 100644 (file)
index 0000000..5842aee
Binary files /dev/null and b/public/images/favicon/favicon.ico differ
diff --git a/public/images/favicon/manifest.json b/public/images/favicon/manifest.json
new file mode 100644 (file)
index 0000000..e967fc5
--- /dev/null
@@ -0,0 +1,18 @@
+{
+    "name": "",
+    "icons": [
+        {
+            "src": "/images/favicon/android-chrome-192x192.png",
+            "sizes": "192x192",
+            "type": "image/png"
+        },
+        {
+            "src": "/images/favicon/android-chrome-512x512.png",
+            "sizes": "512x512",
+            "type": "image/png"
+        }
+    ],
+    "theme_color": "#ffffff",
+    "background_color": "#ffffff",
+    "display": "standalone"
+}
diff --git a/public/images/favicon/mstile-150x150.png b/public/images/favicon/mstile-150x150.png
new file mode 100644 (file)
index 0000000..928fe05
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat fc323034e5b15647a98909a7cce05bb80eecef93                 5784
diff --git a/public/images/favicon/safari-pinned-tab.svg b/public/images/favicon/safari-pinned-tab.svg
new file mode 100644 (file)
index 0000000..da1d457
--- /dev/null
@@ -0,0 +1,85 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
+ "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
+<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
+ width="512.000000pt" height="512.000000pt" viewBox="0 0 512.000000 512.000000"
+ preserveAspectRatio="xMidYMid meet">
+<metadata>
+Created by potrace 1.11, written by Peter Selinger 2001-2013
+</metadata>
+<g transform="translate(0.000000,512.000000) scale(0.100000,-0.100000)"
+fill="#000000" stroke="none">
+<path d="M2379 4963 c-1 -10 -2 -85 -3 -168 l-1 -150 -160 0 -160 0 -3 -168
+-2 -167 47 -1 c27 0 100 -1 163 -2 l115 -2 1 -173 0 -173 -35 -33 c-120 -110
+-227 -244 -237 -296 0 -3 -6 -25 -13 -49 -23 -82 -40 -186 -42 -269 -2 -93 -8
+-132 -19 -132 -4 0 -74 36 -156 80 -81 44 -149 80 -150 80 -1 0 -19 8 -40 17
+-22 9 -41 17 -44 18 -3 0 -10 3 -16 7 -15 10 -160 46 -219 54 -72 10 -300 12
+-365 2 -153 -23 -378 -121 -489 -213 -52 -43 -136 -133 -176 -190 -180 -252
+-206 -530 -74 -805 84 -176 177 -292 453 -565 l213 -210 2 -190 c5 -364 17
+-639 32 -711 7 -39 19 -60 47 -86 44 -40 123 -86 207 -121 117 -47 100 -41
+140 -52 17 -4 35 -10 40 -14 6 -3 15 -6 20 -7 6 -1 37 -10 70 -19 76 -21 161
+-42 200 -49 17 -2 41 -7 55 -10 58 -13 77 -16 120 -21 25 -3 56 -7 70 -10 69
+-14 250 -20 585 -20 390 0 553 8 665 31 14 3 39 7 55 9 17 1 55 8 85 15 30 6
+69 14 85 17 17 2 71 16 120 30 50 14 97 27 105 28 8 2 16 4 18 5 1 2 5 3 10 5
+4 1 16 5 27 9 11 4 52 19 90 33 87 32 202 94 242 130 31 28 55 65 60 93 9 54
+14 122 18 240 2 74 7 225 11 335 3 110 7 230 8 267 l2 67 65 62 c35 33 120
+116 187 182 419 413 559 725 470 1047 -7 25 -13 47 -14 50 0 3 -6 19 -13 35
+-131 321 -408 538 -766 602 -22 4 -110 7 -195 7 -169 -1 -273 -17 -395 -62
+-64 -24 -205 -93 -231 -113 -26 -21 -175 -91 -181 -85 -4 3 -8 43 -9 89 -4
+209 -38 342 -116 455 -16 23 -73 86 -125 139 l-96 96 1 141 c0 78 1 156 1 173
+l1 33 161 -2 c106 -1 163 2 167 9 5 9 8 298 3 323 -1 3 -75 5 -166 5 l-165 -1
+-1 30 c0 17 -1 93 -1 169 l0 137 -179 0 c-163 0 -179 -2 -180 -17z m285 -1203
+c98 -44 194 -185 213 -311 10 -63 9 -189 -1 -271 -11 -87 -57 -214 -151 -415
+-24 -50 -46 -101 -50 -112 -3 -12 -10 -21 -15 -21 -4 0 -11 -11 -14 -25 -10
+-39 -77 -146 -89 -142 -12 4 -107 174 -101 180 3 2 -2 10 -11 17 -8 7 -15 16
+-15 21 0 5 -16 44 -36 86 -91 199 -139 329 -149 405 -11 85 -8 279 5 328 35
+129 126 240 228 276 49 17 128 11 186 -16z m-1245 -490 c100 -19 209 -55 257
+-87 16 -10 31 -17 34 -16 17 8 196 -123 288 -211 154 -146 325 -411 387 -596
+36 -110 60 -213 70 -305 3 -27 8 -70 11 -95 11 -97 7 -281 -7 -295 -18 -17
+-116 -30 -304 -40 -148 -8 -318 -22 -380 -31 -135 -19 -170 -26 -377 -72 -133
+-30 -161 -25 -260 44 -140 99 -238 185 -420 367 -258 260 -330 401 -331 647 0
+132 11 176 71 299 41 83 246 281 290 281 6 0 12 4 14 8 6 16 170 87 228 99 14
+2 43 8 65 12 69 14 263 9 364 -9z m2661 7 c76 -18 119 -31 150 -44 270 -115
+439 -297 490 -527 10 -47 14 -191 6 -248 -16 -113 -88 -259 -181 -368 -39 -46
+-321 -328 -360 -360 -17 -14 -55 -45 -85 -70 -30 -25 -57 -47 -60 -50 -3 -3
+-39 -27 -80 -55 -72 -48 -78 -50 -142 -49 -37 1 -75 5 -85 9 -20 9 -25 10 -68
+19 -16 3 -50 10 -75 15 -170 38 -291 54 -480 66 -155 9 -321 22 -385 30 -11 1
+-28 3 -37 4 -42 3 -47 23 -43 190 2 88 6 167 8 178 3 10 8 41 11 68 34 306
+240 683 501 912 193 170 375 257 586 279 35 3 66 8 68 10 6 6 232 -3 261 -9z
+m-909 -2041 c176 -9 246 -19 383 -53 247 -60 370 -151 296 -218 -26 -23 -75
+-21 -230 10 -134 27 -284 54 -340 60 -19 2 -53 6 -75 9 -22 3 -69 8 -105 11
+-36 4 -83 8 -105 10 -228 22 -667 22 -880 0 -22 -2 -69 -7 -105 -10 -104 -10
+-216 -24 -240 -30 -8 -2 -35 -7 -60 -10 -25 -4 -112 -20 -195 -36 -188 -38
+-218 -39 -248 -8 -13 13 -22 30 -21 37 1 6 2 16 3 22 2 20 58 63 118 91 65 31
+245 79 353 94 67 9 136 14 265 21 72 3 131 7 133 8 4 5 960 -3 1053 -8z m-381
+-371 c125 -7 306 -22 360 -30 14 -2 48 -6 75 -10 28 -3 66 -9 85 -11 74 -10
+248 -46 315 -66 85 -24 204 -80 228 -106 33 -37 28 -89 -11 -118 -14 -10 -97
+3 -197 30 -5 2 -28 7 -50 11 -49 11 -47 10 -65 17 -8 4 -69 18 -135 32 -107
+22 -155 31 -286 50 -92 14 -269 20 -549 21 -361 0 -509 -9 -700 -44 -30 -6
+-66 -12 -80 -15 -14 -2 -81 -18 -150 -36 -69 -17 -134 -33 -145 -35 -11 -3
+-59 -13 -107 -24 l-87 -19 -20 22 c-11 11 -23 33 -26 48 -19 75 164 162 450
+214 41 7 161 26 195 30 19 2 50 6 69 9 18 3 68 8 110 10 42 3 92 7 111 10 19
+2 87 7 150 11 63 3 116 7 118 9 4 4 223 -2 342 -10z"/>
+<path d="M2525 3631 c-31 -13 -71 -58 -93 -104 -36 -77 -44 -226 -17 -344 3
+-13 7 -33 10 -44 17 -78 85 -227 117 -256 19 -17 20 -17 35 2 32 42 94 183
+114 260 20 79 29 235 17 300 -16 82 -60 155 -110 181 -30 16 -44 16 -73 5z"/>
+<path d="M1197 3094 c-1 -1 -31 -4 -67 -7 -97 -9 -223 -49 -282 -89 -14 -10
+-29 -18 -32 -18 -34 0 -206 -193 -206 -231 0 -5 -4 -17 -9 -27 -39 -71 -51
+-165 -31 -241 13 -52 81 -192 118 -241 64 -87 236 -266 369 -387 48 -43 101
+-91 118 -107 58 -54 74 -58 177 -41 51 8 104 17 118 20 14 3 41 8 60 11 19 3
+80 14 135 24 117 21 143 26 310 51 44 6 91 13 105 14 113 14 139 17 169 19 20
+1 37 10 43 20 22 39 -19 225 -92 416 -96 254 -210 452 -319 552 -166 154 -387
+249 -604 260 -42 3 -78 3 -80 2z"/>
+<path d="M3858 3095 c-2 -1 -34 -5 -73 -8 -68 -6 -144 -21 -175 -34 -8 -3 -20
+-7 -25 -8 -23 -5 -121 -49 -135 -60 -8 -7 -25 -16 -37 -19 -13 -4 -23 -12 -23
+-17 0 -5 -7 -9 -15 -9 -8 0 -15 -4 -15 -10 0 -5 -5 -10 -11 -10 -6 0 -17 -6
+-24 -12 -8 -7 -44 -40 -80 -73 -82 -73 -139 -152 -198 -270 -59 -120 -87 -182
+-87 -194 0 -6 -4 -11 -10 -11 -5 0 -10 -9 -10 -19 0 -11 -4 -23 -10 -26 -5 -3
+-10 -13 -10 -22 0 -8 -6 -29 -14 -46 -37 -82 -85 -266 -86 -327 -1 -58 3 -70
+19 -71 9 -1 27 -2 41 -4 14 -2 52 -6 85 -10 33 -3 71 -8 85 -10 14 -3 43 -7
+65 -10 64 -10 84 -13 190 -30 55 -9 109 -18 120 -19 21 -3 126 -23 319 -62 66
+-13 125 -20 132 -16 53 30 475 446 546 539 123 159 158 294 113 438 -42 135
+-126 248 -239 320 -73 47 -215 93 -307 101 -41 3 -86 7 -101 9 -15 2 -28 2
+-30 0z"/>
+</g>
+</svg>
diff --git a/public/images/mark.svg b/public/images/mark.svg
new file mode 100644 (file)
index 0000000..3ee8e35
--- /dev/null
@@ -0,0 +1,5 @@
+<?xml version="1.0" standalone="yes"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Mark possible moves - vchess" viewbox="0 0 599 599" width="600" height="600">
+       <circle id="mark_circle" fill="#90c" cx="300" cy="300" r="200" />
+</svg>
diff --git a/public/images/pieces/Checkered/cb.svg b/public/images/pieces/Checkered/cb.svg
new file mode 100644 (file)
index 0000000..3f32179
--- /dev/null
@@ -0,0 +1,173 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="100%"
+   width="100%"
+   version="1.1"
+   viewBox="0 0 2048 2048"
+   id="svg3451"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="cb.svg">
+  <metadata
+     id="metadata3473">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3471" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     id="namedview3469"
+     showgrid="false"
+     inkscape:zoom="0.16296602"
+     inkscape:cx="1024"
+     inkscape:cy="1146.725"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3451" />
+  <path
+     style="color:black;"
+     d="m1024 1166q97 0 186 15 98-35 142-109 38-64 38-141 0-46-23-101t-75-101q-59-49-129-107t-139-137q-70 78-140 136t-128 108q-53 45-75 100t-23 102q0 77 37 141 43 74 143 109 88-15 186-15z"
+     fill-rule="nonzero"
+     display="block"
+     fill="#fff"
+     id="path3453" />
+  <path
+     style="color:black;"
+     d="m988 1138l-83 1q-34 0-34 34t34 34h83v86q0 35 36 35 35 0 35-35v-86h86q33 0 33-34t-33-34h-86v-82q0-36-35-36-36 0-36 36v81zm36-578q68 0 132 11t125 28q-117 31-257 31-142 0-257-31 58-16 123-27t134-12zm0 1089q68 0 68 68t-68 68-68-68 68-68zm0-949q117 0 225-23l-48 123q-88 14-177 14-91 0-178-14l-48-123q107 23 226 23zm0 182q97 0 186-15 98 35 142 109 38 64 38 141 0 46-23 101t-75 101q-59 49-129 107t-139 137q-70-78-140-136t-128-108q-53-45-75-100t-23-102q0-77 37-141 43-74 143-109 88 15 186 15zm-36-377h-32q-56-90-107-113-24-12-53-22t-67-10q-7 0-107 16-48 7-76 15t-44 10q-57 7-133-6-46-8-86-29l48-78q12 12 31 15t36 8q42 7 80 2 13-3 51-7t101-15q75-11 102-11 105 0 161 40 34 26 64 72t31 113zm36-113q-14-57-34-79t-53-46q-36-25-85-42t-109-9l-281 39q-17 2-30 0t-26-2q-21 0-53-9t-51-28l-97 159q18 20 32 28t33 17q58 27 124 33 28 2 55 1t56 2q54-9 108-16t110-16q60 0 81 12 11 6 35 22t48 47q-53 6-108 20t-97 31l104 258q-78 45-109 72t-49 64q-26 46-33 89t-7 77q1 60 28 132t104 130q63 48 123 99t119 119q-74 38-74 121 0 56 39 96t97 40q56 0 96-40t40-96q0-82-74-121 58-68 117-119t125-99q75-57 102-129t29-133q0-34-7-77t-32-89q-20-36-50-63t-108-73l104-258q-44-16-99-30t-106-21q23-31 47-47t36-22q21-12 81-12 54 8 108 15t110 17q27-3 54-2t57-1q64-6 124-33 18-9 32-17t33-28l-98-159q-18 18-50 27t-53 10q-13 0-26 2t-31 0l-280-39q-60-9-111 8t-85 45q-33 27-52 46t-33 77zm35 113q0-66 30-112t66-73q55-40 161-40 26 0 102 11 62 10 100 14t51 8q38 5 80-2 16-4 35-7t33-16l48 78q-41 21-87 29-76 13-133 6-17-2-44-10t-75-15q-101-16-107-16-39 0-68 10t-52 22q-53 24-108 113h-32z"
+     fill-rule="nonzero"
+     transform="translate(0,2048) scale(1,-1)"
+     display="block"
+     fill="#000"
+     id="path3455" />
+  <g
+     fill-rule="nonzero"
+     fill="#fff"
+     id="g3457">
+    <path
+       style="color:black;"
+       d="m1024 1488q68 0 132-11t125-28q-117-31-257-31-142 0-257 31 58 16 123 27t134 12z"
+       display="block"
+       id="path3459" />
+    <path
+       style="color:black;"
+       d="m1024 399q68 0 68-68t-68-68-68 68 68 68z"
+       display="block"
+       id="path3461" />
+    <path
+       style="color:black;"
+       d="m1024 1348q117 0 225 23l-48-123q-88-14-177-14-91 0-178 14l-48 123q107-23 226-23z"
+       display="block"
+       id="path3463" />
+    <path
+       style="color:black;"
+       d="m988 1543h-32q-56 90-107 113-24 12-53 22t-67 10q-7 0-107-16-48-7-76-15t-44-10q-57-7-133 6-46 8-86 29l48 78q12-12 31-15t36-8q42-7 80-2 13 3 51 7t101 15q75 11 102 11 105 0 161-40 34-26 64-72t31-113z"
+       display="block"
+       id="path3465" />
+    <path
+       style="color:black;"
+       d="m1059 1543q0 66 30 112t66 73q55 40 161 40 26 0 102-11 62-10 100-14t51-8q38-5 80 2 16 4 35 7t33 16l48-78q-41-21-87-29-76-13-133-6-17 2-44 10t-75 15q-101 16-107 16-39 0-68-10t-52-22q-53-24-108-113h-32z"
+       display="block"
+       id="path3467" />
+  </g>
+  <path
+     style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1024,234.30508 8.678,1310.37292"
+     id="path3475"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1111.2136,1167.086 -80.2712,-8.7909 0,-59.3374 c 0,-47.7667 3.3843,-62.7217 17.3559,-76.6933 13.1116,-13.1116 17.3559,-28.92654 17.3559,-64.67065 l 0,-47.31472 54.2373,-2.58359 54.2373,-2.58358 0,-30.37288 0,-30.37288 -54.2373,-2.58358 -54.2373,-2.58358 0,-47.31472 c 0,-35.74411 -4.2443,-51.55905 -17.3559,-64.67066 -15.4106,-15.41063 -17.3559,-28.92655 -17.3559,-120.5884 l 0,-103.23248 50.1326,48.99519 c 27.5729,26.94735 91.6713,83.4419 142.4409,125.54344 97.8599,81.15198 127.0162,116.80329 149.3698,182.64408 35.0159,103.13698 -6.9542,224.29991 -97.7872,282.30091 -51.1869,32.6852 -66.2179,34.9056 -163.8849,24.2097 z"
+     id="path3477"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 810.54913,1348.7828 c 25.18443,-81.219 35.53115,-96.45 69.67182,-102.5607 18.46288,-3.3046 57.97566,-6.2334 87.80617,-6.5084 l 54.23728,-0.5001 0.1185,32.5423 c 0.065,17.8983 2.3452,40.8397 5.0668,50.9808 4.6873,17.4657 0.9041,18.7677 -71.71172,24.68 -42.16303,3.4328 -93.36631,9.296 -113.78506,13.0291 -35.18449,6.4328 -36.82595,5.8231 -31.40383,-11.663 z"
+     id="path3479"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 853.82103,1467.2598 c -43.65686,-8.3868 -64.17424,-15.6905 -56.36083,-20.0631 16.71852,-9.3562 138.13023,-25.7459 190.72027,-25.7459 l 42.76193,0 0,30.3729 0,30.3729 -54.23732,-0.8746 c -29.8305,-0.4811 -85.12833,-6.8091 -122.88405,-14.0622 z"
+     id="path3481"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 709.85763,1764.1017 c -7.15932,-1.6257 -63.19274,-9.5928 -124.51872,-17.7046 -103.84965,-13.7366 -207.58053,-13.7784 -240.71572,-0.097 -9.74741,4.0247 -20.41864,-4.3481 -36.4857,-28.627 l -22.70888,-34.3155 34.88955,-13.96 c 59.75778,-23.9103 148.97064,-26.1903 246.35303,-6.2959 150.71062,30.7888 187.75392,32.2871 247.33925,10.0036 39.60833,-14.8125 62.86387,-31.0865 95.58662,-66.8904 23.78399,-26.0234 43.24362,-50.9057 43.24362,-55.294 0,-4.3882 7.98712,-7.9786 17.74915,-7.9786 15.74906,0 17.09994,3.6671 11.98786,32.5423 -13.71206,77.4517 -75.74507,155.1048 -138.21159,173.0135 -39.3075,11.2693 -114.95189,20.0443 -134.50847,15.6035 z"
+     id="path3483"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#ffffff"
+     d="m 1030.9424,332.3661 c 0,-47.84375 3.0088,-65.08474 11.3583,-65.08474 22.0679,0 41.1676,22.13302 46.2786,53.62822 4.3157,26.59489 1.4726,35.57656 -17.1596,54.20882 -34.7652,34.76519 -40.4773,28.73203 -40.4773,-42.7523 z"
+     id="path3485"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1026.2876,716.43404 3.0681,322.15306"
+     id="path3489"
+     inkscape:connector-curvature="0" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3495"
+     width="127.32716"
+     height="58.294361"
+     x="1029.3557"
+     y="845.29529" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3497"
+     width="26.079058"
+     height="87.441544"
+     x="1029.3557"
+     y="906.65771" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3509"
+     width="24.949152"
+     height="106.84746"
+     x="1029.9661"
+     y="735.45764" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3511"
+     width="24.40678"
+     height="18.440678"
+     x="1029.9661"
+     y="995.79663" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3513"
+     width="18.983051"
+     height="9.2203388"
+     x="1030.5084"
+     y="727.32202" />
+  <rect
+     style="fill:#ffffff"
+     id="rect3515"
+     width="15.18644"
+     height="45.016949"
+     x="1157.4237"
+     y="853.15253" />
+</svg>
diff --git a/public/images/pieces/Checkered/cn.svg b/public/images/pieces/Checkered/cn.svg
new file mode 100644 (file)
index 0000000..5f7b3bc
--- /dev/null
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="100%"
+   width="100%"
+   version="1.1"
+   viewBox="0 0 2048 2048"
+   id="svg3562"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="cn.svg">
+  <metadata
+     id="metadata3572">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3570" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="905"
+     inkscape:window-height="1028"
+     id="namedview3568"
+     showgrid="false"
+     inkscape:zoom="1.3037281"
+     inkscape:cx="400.29223"
+     inkscape:cy="706.38371"
+     inkscape:window-x="10"
+     inkscape:window-y="24"
+     inkscape:window-maximized="0"
+     inkscape:current-layer="svg3562" />
+  <path
+     style="color:black;"
+     d="m1756 1774q-1 0 2-54t3-118q1-125 0-258t-36-267q-34-128-75-218t-89-157q-72-108-196-183t-259-98q9 49 8 96-2 36-34 36-37 0-33-36 3-132-94-226-76 80-82 186-2 35-36 31-32-1-32-37 0 0 2-8-41 13-86 37-29 20-47-10t16-47q43-22 65-33-86-88-196-142 12 139 76 263 17 26-8 46-28 22-47-7-7-10-20-36-21 21-28 31-7 9-24 40t-26 51q-9 25-8 40t3 35q-9 59-40 111t-81 127q-47 72-72 108t-38 92q-9 34 0 82t39 76q46 47 89 43 14 0 37-11t37-42q26-57 43-57 25 0 27 28 0 6-16 50-9 20-24 42-19 26-17 22 16 57 53 20 11-11 25-41t44-81q35-59 75-96t71-60q18-13 44-30t70-35q35-14 77-34t76-53q46-45 71-111 13-37 10-91-9-34 34-34 32 0 36 33 0 113-64 206 21 64 11 140-9 61-42 130t-136 155q-207 172-196 354 0 0 170 0t321 0h547z"
+     fill-rule="nonzero"
+     display="block"
+     fill="#fff"
+     id="path3564" />
+  <path
+     style="color:black;"
+     d="m697 1359q13-20 10-42-10-64-71-54-18 3-29 12-4-5-12-22-11-32-42-22-31 12-24 45 45 115 163 158 34 10 45-20 12-32-18-44-6-3-11-5t-11-6zm-297-477q-29-18-35-48 1-33-31-36-35-4-36 30 4 66 59 105 26 21 48-4 22-27-5-47zm679 815q157-10 291-81t228-182q66-78 124-188t94-233q40-143 50-300t11-292v-218t-155 0-404 0h-671q-9 0-9 49t7 79q4 24 19 68t50 107q16 32 76 93t138 143q45 46 70 116t22 127q-37-30-81-49-212-76-307-220-7-9-45-81-20-38-34-52-19-19-55-21-56-3-87 54-42-12-75-10-56 21-81 45-51 51-66 102t-16 110q0 84 104 222 122 159 130 242 0 36 7 81 6 31 25 60 13 20 17 27t17 23q9 12 15 18t15 18q11 13 28 30-53 146-43 301 199-71 334-223 33 113 130 183 80-56 127-148zm677-1423q-1 0 2 54t3 118q1 125 0 258t-36 267q-34 128-75 218t-89 157q-72 108-196 183t-259 98q9-49 8-96-2-36-34-36-37 0-33 36 3 132-94 226-76-80-82-186-2-35-36-31-32 1-32 37 0 0 2 8-41-13-86-37-29-20-47 10t16 47q43 22 65 33-86 88-196 142 12-139 76-263 17-26-8-46-28-22-47 7-7 10-20 36-21-21-28-31-7-9-24-40t-26-51q-9-25-8-40t3-35q-9-59-40-111t-81-127q-47-72-72-108t-38-92q-9-34 0-82t39-76q46-47 89-43 14 0 37 11t37 42q26 57 43 57 25 0 27-28 0-6-16-50-9-20-24-42-19-26-17-22 16-57 53-20 11 11 25 41t44 81q35 59 75 96t71 60q18 13 44 30t70 35q35 14 77 34t76 53q46 45 71 111 13 37 10 91-9 34 34 34 32 0 36-33 0-113-64-206 21-64 11-140-9-61-42-130t-136-155q-207-172-196-354 0 0 170 0t321 0h547z"
+     fill-rule="nonzero"
+     transform="translate(0,2048) scale(1,-1)"
+     display="block"
+     fill="#000"
+     id="path3566" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="M 357.9661,952.40678 1685.6949,945.8983"
+     id="path3574"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1063.0508,1197.5593 685.5594,-4.339"
+     id="path3576"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1080.5682,1191.0908 c 0.6369,-2.7664 3.7679,-15.7688 6.9579,-28.8942 4.732,-19.4704 6.0213,-30.9091 7.0023,-62.1256 1.2626,-40.1787 -0.5958,-60.8221 -8.0223,-89.1089 l -4.0396,-15.38641 11.7428,-19.74039 c 6.4585,-10.85721 12.4947,-21.04786 13.4137,-22.64589 1.3773,-2.39488 52.2526,-3.12149 289.4818,-4.13448 l 287.8109,-1.22896 12.0235,37.76159 c 22.642,71.11094 37.8116,130.22524 46.434,180.94804 l 4.0567,23.8644 -88.0336,1.3509 c -48.4185,0.7431 -198.7229,2.0302 -334.0098,2.8603 l -245.9762,1.5093 1.1579,-5.0297 z"
+     id="path3578"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1106.4407,518.50847 -2.1695,266.84746"
+     id="path3582"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1114.3974,938.19661 c 7.2163,-14.18147 17.0605,-44.48553 23.1361,-71.22143 7.9074,-34.79704 9.8849,-82.73454 3.8796,-94.04809 -5.4523,-10.27165 -13.5414,-15.60995 -25.7366,-16.98452 l -10.3514,-1.16675 1.5199,-107.03008 c 1.224,-86.19349 2.1351,-108.50239 4.6798,-114.59281 5.1044,-12.21644 3.9846,-57.13704 -2.5112,-100.73763 l -1.4169,-9.51013 10.3426,1.55096 c 48.684,7.30062 134.5146,36.30124 189.9928,64.19514 147.1546,73.98786 242.3085,172.54974 323.7881,335.3845 16.8632,33.70069 33.1432,70.93839 44.5388,101.87505 l 6.4626,17.5447 -130.342,1.43835 c -71.6882,0.79109 -200.4926,1.43833 -286.2321,1.43833 l -155.8899,0 4.1398,-8.13559 z"
+     id="path3584"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 476.11726,1432.0156 c -2.19518,-1.2761 -6.74402,-8.141 -10.10853,-15.2552 l -6.11731,-12.9351 12.78498,-17.7635 c 7.03174,-9.7699 16.30273,-24.4136 20.60223,-32.5414 10.20434,-19.2905 22.62862,-56.394 22.61834,-67.5467 -0.0109,-12.4981 -6.50639,-22.0734 -17.13171,-25.2568 -17.66266,-5.2919 -27.92479,4.5705 -50.18259,48.2278 -14.73078,28.8934 -22.16355,38.5018 -36.10366,46.6713 -39.72557,23.2807 -76.36449,16.7134 -120.34947,-21.5718 -23.24785,-20.2353 -37.62943,-44.4324 -45.67966,-76.8562 -3.75967,-15.1428 -4.7163,-25.3004 -4.65548,-49.4321 0.0698,-27.6874 0.69379,-32.4829 7.05738,-54.2373 10.85588,-37.1115 22.02691,-57.7305 71.21017,-131.4366 l 45.72358,-68.52138 329.23781,-1.45877 c 181.0808,-0.80233 329.68846,-1.00811 330.23926,-0.4573 1.8488,1.84878 -21.1889,28.94005 -37.80784,44.46032 -31.00374,28.95413 -57.08787,43.58153 -144.6994,81.14473 -63.69334,27.3083 -105.46308,54.0133 -163.04683,104.2424 -59.44546,51.8531 -88.10817,90.9659 -138.09163,188.4382 -19.73563,38.4863 -31.62153,55.3643 -43.20842,61.3561 -7.18023,3.713 -16.627,4.0221 -22.29122,0.7293 z M 338.14013,1250.0357 c 17.43758,-3.3069 28.00201,-15.7019 28.11769,-32.9897 0.0917,-13.705 7.72069,-25.7935 28.69768,-45.4727 20.06786,-18.8262 20.06823,-18.8268 20.06823,-29.5552 0,-18.2069 -15.27304,-35.0679 -33.31791,-36.782 -8.99003,-0.854 -11.52075,0.012 -23.55984,8.0659 -29.76481,19.911 -51.00299,51.1165 -57.94691,85.1421 -4.26583,20.9028 -4.26256,25.5405 0.0256,36.2576 3.62522,9.0603 9.68075,14.3042 18.41582,15.9475 2.89555,0.5447 5.86359,1.1234 6.59564,1.2859 0.73205,0.1625 6.53887,-0.6923 12.90404,-1.8994 z"
+     id="path3586"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#ffffff"
+     d="m 315.76954,1248.4466 c -16.86984,-5.9023 -21.14247,-23.9399 -13.15718,-55.5454 7.64358,-30.2529 24.83813,-55.2854 51.88812,-75.5408 9.79859,-7.3373 14.72259,-9.8856 21.53561,-11.145 10.59059,-1.9578 22.6263,4.3999 31.05765,16.4057 6.5262,9.2929 8.64153,17.3435 6.49617,24.7233 -2.31861,7.9757 -6.89367,13.3933 -17.56617,20.801 -8.08091,5.6088 -18.44331,16.2219 -22.41378,22.9559 -5.96206,10.1117 -7.85228,16.1997 -9.47096,30.5039 -2.15352,19.0306 -14.15035,28.1862 -36.79907,28.0841 -5.32749,-0.024 -9.3093,-0.4517 -11.57039,-1.2427 z"
+     id="path3590"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/public/images/pieces/Checkered/cp.svg b/public/images/pieces/Checkered/cp.svg
new file mode 100644 (file)
index 0000000..39a8b13
--- /dev/null
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="100%"
+   width="100%"
+   version="1.1"
+   viewBox="0 0 2048 2048"
+   id="svg2"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="cp.svg">
+  <metadata
+     id="metadata12">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs10" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     id="namedview8"
+     showgrid="false"
+     inkscape:zoom="0.11523438"
+     inkscape:cx="1024"
+     inkscape:cy="1024"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg2" />
+  <path
+     style="color:black;"
+     d="m1024 273h491q21 72 21 141 0 156-86 283t-223 187q-66 5-66 72 0 53 67 78 93 65 93 172 0 77-52 135t-126 67q-60 5-60 68 0 28 22 52 54 42 54 110 0 56-40 96t-95 40q-57 0-96-40t-40-96q0-67 54-110 22-22 22-52 0-63-59-68-75-9-126-67t-52-135q0-107 93-172 67-26 67-78 0-67-67-72-136-60-222-187t-86-283q0-74 21-141h491zm0-68h-540q-40 100-40 209 0 185 105 332t270 210q-71 33-115 99t-45 151q0 105 70 182t172 89q-81 61-81 161 0 84 59 144t145 60q84 0 144-60t60-144q0-100-81-161 102-12 172-89t70-182q0-84-45-150t-116-100q165-63 270-210t105-332q0-108-39-209h-540z"
+     fill-rule="nonzero"
+     transform="translate(0,2048) scale(1,-1)"
+     display="block"
+     fill="#000"
+     id="path4" />
+  <path
+     style="color:black;"
+     d="m1024 1775h491q21-72 21-141 0-156-86-283t-223-187q-66-5-66-72 0-53 67-78 93-65 93-172 0-77-52-135t-126-67q-60-5-60-68 0-28 22-52 54-42 54-110 0-56-40-96t-95-40q-57 0-96 40t-40 96q0 67 54 110 22 22 22 52 0 63-59 68-75 9-126 67t-52 135q0 107 93 172 67 26 67 78 0 67-67 72-136 60-222 187t-86 283q0 74 21 141h491z"
+     fill-rule="nonzero"
+     display="block"
+     fill="#fff"
+     id="path6" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 850.44068,1102.1017 329.76272,0"
+     id="path3340"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1024,242.98305 0,1544.67795"
+     id="path3342"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1030.9424,687.22195 0,-413.14415 23.3351,5.85674 c 60.5135,15.18791 98.1564,65.30088 98.1564,130.67282 0,44.6744 -8.419,64.74371 -44.6625,106.46748 -46.9025,53.99453 -27.483,114.40491 40.9006,127.23374 103.2185,19.36391 168.9829,99.55401 168.4527,205.40332 -0.349,69.65536 -29.6897,112.33403 -129.5206,188.399 -16.6997,12.7241 -26.4922,27.9607 -26.4922,41.2203 0,20.3914 -1.991,21.0349 -65.0848,21.0349 l -65.0847,0 0,-413.14415 z"
+     id="path3344"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 530.51551,1757.722 c -11.73065,-18.6934 -13.91985,-183.3689 -3.12874,-235.3494 27.82654,-134.0398 139.55087,-279.7599 256.54648,-334.6092 33.23807,-15.5826 66.29048,-31.202 73.4498,-34.71 7.15932,-3.508 16.87177,-14.8451 21.58321,-25.1937 7.71721,-16.9507 15.24346,-18.8156 75.93221,-18.8156 l 67.36593,0 0,329.7627 0,329.7627 -242.4709,0 c -184.56097,0 -244.09665,-2.5907 -249.27799,-10.8475 z"
+     id="path3346"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/public/images/pieces/Checkered/cq.svg b/public/images/pieces/Checkered/cq.svg
new file mode 100644 (file)
index 0000000..bf3e849
--- /dev/null
@@ -0,0 +1,189 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="100%"
+   width="100%"
+   version="1.1"
+   viewBox="0 0 2048 2048"
+   id="svg3895"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="cq.svg">
+  <metadata
+     id="metadata3933">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3931" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     id="namedview3929"
+     showgrid="false"
+     inkscape:zoom="0.44873047"
+     inkscape:cx="1024"
+     inkscape:cy="1024"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3895" />
+  <path
+     style="color:black;"
+     d="m1024 1621q-57 0-96 40t-40 97q0 56 39 96t97 40q56 0 96-40t41-96q0-57-40-97t-97-40zm0 70q67 0 67 67 0 66-67 66-66 0-66-66 0-67 66-67zm509-1007q-193 49-505 49-320 0-511-50l15-96q195 46 496 46 299 0 488-45l17 96zm25 60 65 115q-48-19-98-19-134 0-214 109-60-50-134-50-96 0-153 75-64-70-153-70-72 0-132 49-84-107-217-107-51 0-101 19l70-120q194 56 533 56 345 0 534-57zm-448 239-85 489-85-483q3 2 14 10 23 45 70 45 51 0 66-45 6-6 20-16zm277-19v463l-165-454q19 7 32 18 20 25 54 25 40 0 64-35 3-4 7-8t8-9zm-562 14-164 449v-457q3 4 9 10 20 42 66 42 38 0 62-32 27-12 27-12zm-254-56-215 371 55-338q57-40 111-40 21 0 49 7zm903-5q23-7 51-7 61 0 114 38l55 346-220-377zm60-506-30 113q-196 43-480 43-281 0-479-43l-31-114q186 56 511 56 317 0 509-55zm106-128q-49-43-220-72t-394-29q-227 0-399 30t-217 75l63 240-28 157-88 153-85 622 49 19 274-462 6 550 68 12 209-553 112 595h69l112-593 207 551 69-12 6-550 275 463 47-22-83-619-89-153-28-159 65-243zm-81 36q-183 76-531 76-355 0-537-78 175-69 534-69 172 0 314 19t220 52zm-955 1252q-57 0-97 39t-40 97q0 56 40 96t97 40q56 0 96-40t40-96q0-57-40-96t-96-40zm0 70q66 0 66 66t-66 66q-67 0-67-66t67-66zm840 0q67 0 67 66t-67 66q-66 0-66-66t66-66zm0-70q-57 0-96 39t-40 97q0 56 39 96t97 40q57 0 97-40t40-96q0-57-40-96t-97-40zm-1208-110q-57 0-96 39t-40 97q0 56 39 96t97 41q57 0 97-40t40-97-40-96-97-40zm0 70q67 0 67 66 0 67-67 67-66 0-66-67 0-66 66-66zm1578 0q66 0 66 66 0 67-66 67-67 0-67-67 0-66 67-66zm0-70q-57 0-97 39t-40 97q0 56 40 96t97 41q56 0 96-40t40-97-40-96-96-40z"
+     fill-rule="nonzero"
+     transform="translate(0,2048) scale(1,-1)"
+     display="block"
+     fill="#000"
+     id="path3897" />
+  <g
+     fill-rule="nonzero"
+     fill="#fff"
+     id="g3899">
+    <path
+       style="color:black;"
+       d="m1024 357q67 0 67-67 0-66-67-66-66 0-66 66 0 67 66 67z"
+       display="block"
+       id="path3901" />
+    <path
+       style="color:black;"
+       d="m1533 1364q-193-49-505-49-320 0-511 50l15 96q195-46 496-46 299 0 488 45l17-96z"
+       display="block"
+       id="path3903" />
+    <path
+       style="color:black;"
+       d="m1558 1304 65-115q-48 19-98 19-134 0-214-109-60 50-134 50-96 0-153-75-64 70-153 70-72 0-132-49-84 107-217 107-51 0-101-19l70 120q194-56 533-56 345 0 534 57z"
+       display="block"
+       id="path3905" />
+    <path
+       style="color:black;"
+       d="m1110 1065-85-489-85 483q3-2 14-10 23-45 70-45 51 0 66 45 6 6 20 16z"
+       display="block"
+       id="path3907" />
+    <path
+       style="color:black;"
+       d="m1387 1084v-463l-165 454q19-7 32-18 20-25 54-25 40 0 64 35 3 4 7 8t8 9z"
+       display="block"
+       id="path3909" />
+    <path
+       style="color:black;"
+       d="m825 1070-164-449v457q3-4 9-10 20-42 66-42 38 0 62 32 27 12 27 12z"
+       display="block"
+       id="path3911" />
+    <path
+       style="color:black;"
+       d="m571 1126-215-371 55 338q57 40 111 40 21 0 49-7z"
+       display="block"
+       id="path3913" />
+    <path
+       style="color:black;"
+       d="m1474 1131q23 7 51 7 61 0 114-38l55-346-220 377z"
+       display="block"
+       id="path3915" />
+    <path
+       style="color:black;"
+       d="m1534 1637-30-113q-196-43-480-43-281 0-479 43l-31 114q186-56 511-56 317 0 509 55z"
+       display="block"
+       id="path3917" />
+    <path
+       style="color:black;"
+       d="m1559 1729q-183-76-531-76-355 0-537 78 175 69 534 69 172 0 314-19t220-52z"
+       display="block"
+       id="path3919" />
+    <path
+       style="color:black;"
+       d="m604 407q66 0 66-66t-66-66q-67 0-67 66t67 66z"
+       display="block"
+       id="path3921" />
+    <path
+       style="color:black;"
+       d="m1444 407q67 0 67-66t-67-66q-66 0-66 66t66 66z"
+       display="block"
+       id="path3923" />
+    <path
+       style="color:black;"
+       d="m236 517q67 0 67-66 0-67-67-67-66 0-66 67 0 66 66 66z"
+       display="block"
+       id="path3925" />
+    <path
+       style="color:black;"
+       d="m1814 517q66 0 66-66 0-67-66-67-67 0-67 67 0 66 67 66z"
+       display="block"
+       id="path3927" />
+  </g>
+  <path
+     style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1016.2002,176.05223 13.3711,1655.78237"
+     id="path3935"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1097.8927,1055.22 c -3.8512,-3.3208 -8.5172,-9.6877 -10.3689,-14.1486 -8.093,-19.4972 -28.3608,-34.0022 -51.2742,-36.6953 l -11.9935,-1.4096 -1.5837,-200.85733 c -1.3789,-174.88427 -0.9022,-222.32668 2.2024,-219.222 0.6751,0.67508 83.3628,473.92123 83.3628,477.10983 0,2.7798 -3.4043,1.2077 -10.3449,-4.777 z"
+     id="path3937"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1372.8592,1066.7465 c -20.9019,-25.8478 -37.3854,-34.492 -65.8135,-34.5135 -19.7859,-0.016 -35.6621,6.4407 -49.9744,20.3208 -8.9525,8.6822 -30.0487,21.4445 -32.0839,19.4093 -0.5049,-0.5049 35.446,-100.92349 79.8908,-223.15241 l 80.8089,-222.23439 0.5773,113.80565 c 0.3176,62.59311 0.3176,165.20064 0,228.01674 l -0.5773,114.21111 -12.8279,-15.8633 z"
+     id="path3939"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1490.427,1134.1797 c -7.3541,-1.3985 -13.3711,-3.5735 -13.3711,-4.8335 0,-2.6768 213.3541,-368.96743 214.3393,-367.98217 0.9771,0.97706 -52.4803,335.68407 -54.0082,338.15637 -2.8857,4.6691 -36.3949,22.3755 -52.1503,27.5563 -30.6346,10.0735 -65.4667,12.6831 -94.8097,7.103 z"
+     id="path3941"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1416.3239,402.21256 c -26.5048,-9.48337 -37.3288,-27.84542 -37.0253,-62.8106 0.3683,-42.43229 20.8673,-62.90952 63.0394,-62.97256 10.5151,-0.0157 23.2258,1.10694 28.2461,2.49478 13.7003,3.78746 26.3355,14.05333 32.3611,26.29276 4.6611,9.46783 5.3099,13.91701 5.3099,36.41353 0,22.0159 -0.678,26.88419 -4.8101,34.54189 -10.9491,20.29095 -25.5604,28.03652 -55.3597,29.34649 -15.6631,0.68855 -22.6206,-0.0357 -31.7614,-3.30629 z"
+     id="path3943"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1787.9185,513.48948 c -28.6032,-9.30226 -41.811,-32.05405 -39.5438,-68.11799 1.3392,-21.30133 5.6944,-32.81347 16.6783,-44.08566 10.739,-11.02088 25.8689,-16.01654 48.5078,-16.01654 23.8961,0 38.2835,5.03887 49.6755,17.39781 11.8528,12.85874 14.9395,22.80939 14.9395,48.16032 0,24.10057 -2.9811,34.79294 -12.827,46.00687 -11.8462,13.49203 -21.911,17.20649 -48.4452,17.87884 -12.8697,0.3261 -25.9129,-0.22454 -28.9851,-1.22365 z"
+     id="path3945"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1019.0973,291.19595 0,-66.03409 16.1567,1.05502 c 34.4836,2.25176 51.8065,20.28283 54.5682,56.79916 2.2787,30.12953 -8.6072,55.21096 -28.3297,65.27263 -7.1598,3.65266 -30.3084,8.86832 -39.6096,8.92453 -2.1662,0.0131 -2.7856,-14.66668 -2.7856,-66.01725 z"
+     id="path3947"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1549.3362,1301.2288 c -0.5925,-0.5924 -13.0866,-4.114 -27.7647,-7.8256 -109.5271,-27.6961 -246.3712,-42.5912 -425.0335,-46.2638 l -70.7552,-1.4545 0.071,-83.7661 0.071,-83.766 10.5145,11.4826 c 14.3946,15.7201 32.0516,29.3231 50.6276,39.0037 65.4837,34.1256 154.8178,25.4646 213.1433,-20.6646 4.4663,-3.5323 8.9897,-6.4224 10.0521,-6.4224 1.0624,0 6.4336,5.6488 11.9361,12.5529 31.9871,40.1351 81.8151,72.65 131.1269,85.566 48.6622,12.7458 107.8765,11.0794 153.4897,-4.3195 7.0532,-2.3811 13.036,-4.1172 13.2952,-3.858 0.2592,0.2592 -13.3837,25.005 -30.3176,54.9907 -21.7709,38.5509 -32.0469,54.7102 -35.084,55.1706 -2.3624,0.3581 -4.7799,0.1665 -5.3723,-0.426 z"
+     id="path3949"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 532.36078,1457.7877 c -1.34024,-4.2159 -14.66887,-91.798 -14.06035,-92.3902 0.27309,-0.2658 16.54179,-4.051 36.15267,-8.4117 109.03938,-24.2458 232.14544,-36.6379 403.9173,-40.6593 l 65.1839,-1.526 0,49.3715 0,49.3714 -9.4712,0.027 c -78.6505,0.2252 -221.56589,7.8705 -293.60606,15.7067 -62.01255,6.7454 -167.92717,24.1481 -183.62162,30.1706 -2.0127,0.7724 -3.94868,0.057 -4.49464,-1.6601 z"
+     id="path3951"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 516.31245,1632.4945 c 0.63724,-2.145 7.34888,-26.965 14.91477,-55.1557 7.56589,-28.1906 14.09034,-51.632 14.49879,-52.0919 1.3963,-1.5722 51.02762,-11.0517 87.83917,-16.777 103.81553,-16.1466 231.82899,-25.8321 341.51904,-25.8393 l 50.69858,-0 0,49.0272 0,49.0272 -17.2709,0.022 c -75.9668,0.096 -209.93544,7.5533 -281.34933,15.6602 -67.895,7.7075 -155.54896,23.7793 -193.88031,35.549 -17.7017,5.4353 -18.41901,5.4599 -16.96981,0.5819 z"
+     id="path3953"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 892.25341,1796.7004 c -154.01595,-6.6842 -281.32833,-25.8628 -372.20479,-56.0697 l -27.71895,-9.2136 9.89088,-4.2205 c 35.34955,-15.0839 104.82228,-34.5539 160.31525,-44.929 91.31945,-17.0733 216.63526,-27.9304 323.34849,-28.0143 l 39.21361,-0.031 1.4567,27.092 c 0.8012,14.9006 1.4567,47.4925 1.4567,72.4266 l 0,45.3345 -48.47006,-0.3452 c -26.65854,-0.1899 -65.93807,-1.1033 -87.28783,-2.0299 z"
+     id="path3955"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/public/images/pieces/Checkered/cr.svg b/public/images/pieces/Checkered/cr.svg
new file mode 100644 (file)
index 0000000..1923486
--- /dev/null
@@ -0,0 +1,143 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   height="100%"
+   width="100%"
+   version="1.1"
+   viewBox="0 0 2048 2048"
+   id="svg3745"
+   inkscape:version="0.91 r13725"
+   sodipodi:docname="cr.svg">
+  <metadata
+     id="metadata3767">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3765" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1920"
+     inkscape:window-height="1056"
+     id="namedview3763"
+     showgrid="false"
+     inkscape:zoom="0.44873047"
+     inkscape:cx="1024"
+     inkscape:cy="1024"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3745" />
+  <path
+     style="color:black;"
+     d="m1161 1706h170v137h274v-375l-222-171v-478l170-170v-205h153v-239h-1365v239h153v205l171 170v478l-222 171v375h273v-137h171v137h274v-137zm478-1330h-1230v-103h1230v103zm-155 204h-920v-136h920v136zm-170 717h-580v-478h580v478zm222 239v239h-137v-137h-308v137h-135v-137h-307v137h-137v-239h1024zm-77-887l-103 102h-663l-105-102h871zm-110 716l127 103h-904l128-103h649z"
+     fill-rule="nonzero"
+     transform="translate(0,2048) scale(1,-1)"
+     display="block"
+     fill="#000"
+     id="path3747" />
+  <g
+     fill-rule="nonzero"
+     fill="#fff"
+     id="g3749">
+    <path
+       style="color:black;"
+       d="m1639 1672h-1230v103h1230v-103z"
+       display="block"
+       id="path3751" />
+    <path
+       style="color:black;"
+       d="m1484 1468h-920v136h920v-136z"
+       display="block"
+       id="path3753" />
+    <path
+       style="color:black;"
+       d="m1314 751h-580v478h580v-478z"
+       display="block"
+       id="path3755" />
+    <path
+       style="color:black;"
+       d="m1536 512v-239h-137v137h-308v-137h-135v137h-307v-137h-137v239h1024z"
+       display="block"
+       id="path3757" />
+  </g>
+  <path
+     style="color:black;"
+     d="m1459 1399-103-102h-663l-105 102h871z"
+     fill-rule="nonzero"
+     display="block"
+     fill="#fff"
+     id="path3759" />
+  <path
+     style="color:black;"
+     d="m1349 683 127-103h-904l128 103h649z"
+     fill-rule="nonzero"
+     display="block"
+     fill="#fff"
+     id="path3761" />
+  <path
+     style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1020.6572,233.99347 -2.2285,1575.55603"
+     id="path3769"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
+     d="m 1348.2481,998.37214 -664.09576,2.22856"
+     id="path3771"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1021.3258,392.88618 0,-118.11099 34.5419,0 34.5419,0 0,67.96953 0,67.96953 154.8814,0 154.8814,0 0,-67.96953 0,-67.96953 67.9695,0 67.9695,0 0,118.11099 0,118.11099 -257.3928,0 -257.3928,0 0,-118.11099 z"
+     id="path3773"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1021.3258,631.33667 0,-51.25571 226.6394,0 c 134.6244,0 225.7798,0.81545 224.5223,2.00852 -1.1644,1.10469 -29.5228,24.16976 -63.0186,51.25571 l -60.9014,49.24719 -163.6209,0 -163.6208,0 0,-51.25571 z"
+     id="path3775"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 1021.3255,874.80131 3e-4,-123.12514 145.9673,0 145.9674,0 0,122.53631 0,122.53631 -145.9677,0.58881 -145.9677,0.58884 4e-4,-123.12513 z"
+     id="path3777"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 733.8481,1114.9232 0,-113.654 142.97008,0 142.97012,0 -1.4598,30.4372 c -0.8029,16.7405 -1.4597,67.8848 -1.4597,113.654 l 0,83.2167 -141.51037,0 -141.51033,0 0,-113.6539 z"
+     id="path3779"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 641.36496,1347.8598 51.25571,-49.98 162.12405,-0.1094 162.12408,-0.1095 0,50.1415 0,50.1415 -213.37979,-0.052 -213.37976,-0.052 51.25571,-49.98 z"
+     id="path3781"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 564.48139,1536.1114 0,-66.8553 226.19369,0 226.19372,0 0,66.8553 0,66.8553 -226.19372,0 -226.19369,0 0,-66.8553 z"
+     id="path3783"
+     inkscape:connector-curvature="0" />
+  <path
+     style="fill:#000000"
+     d="m 410.71425,1723.3062 0,-51.2557 303.07726,0 303.07729,0 0,51.2557 0,51.2557 -303.07729,0 -303.07726,0 0,-51.2557 z"
+     id="path3785"
+     inkscape:connector-curvature="0" />
+</svg>
diff --git a/public/images/pieces/LICENSE b/public/images/pieces/LICENSE
new file mode 100644 (file)
index 0000000..9d98b4a
--- /dev/null
@@ -0,0 +1,5 @@
+SVG images found on chesstempo website:
+
+https://www4.chesstempo.com/images/pieces/svg/merida/whitepawn.vers1.svg (...)
+
++ Adaptation for checkered pieces
diff --git a/public/images/pieces/bb.svg b/public/images/pieces/bb.svg
new file mode 100644 (file)
index 0000000..f0a098c
--- /dev/null
@@ -0,0 +1,10 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1290 582l-42 102q-102 22-224 22-121 0-222-22l-42-101q124 31 264 31 138 0 266-32zm-84 206l-29 70v27q-76 11-153 11-75 0-152-11l-1-27-27-70q85 15 180 15 96 0 182-15zm-35-378q-40 30-80 95h-32q0-49 23-95h89zm-206 0q23 49 23 95h-32q-39-64-81-95h90zm59-18q-14-57-34-79t-53-46q-36-25-85-42t-109-9l-281 39q-17 2-30 0t-26-2q-21 0-53-9t-51-28l-97 159q18 20 32 28t33 17q58 27 124 33 28 2 55 1t56 2q54-9 108-16t110-16q60 0 81 12 11 6 35 22t48 47q-53 6-108 20t-97 31l104 258q-78 45-109 72t-49 64q-26 46-33 89t-7 77q1 60 28 132t104 130q63 48 123 99t119 119q-74 38-74 121 0 56 39 96t97 40q56 0 96-40t40-96q0-82-74-121 58-68 117-119t125-99q75-57 102-129t29-133q0-34-7-77t-32-89q-20-36-50-63t-108-73l104-258q-44-16-99-30t-106-21q23-31 47-47t36-22q21-12 81-12 54 8 108 15t110 17q27-3 54-2t57-1q64-6 124-33 18-9 32-17t33-28l-98-159q-18 18-50 27t-53 10q-13 0-26 2t-31 0l-280-39q-60-9-111 8t-85 45q-33 27-52 46t-33 77zm-37 744v-85q0-37 37-37t37 37v86h90q35 0 35 36t-35 36h-90v90q0 37-37 37t-37-37v-90h-88q-35 0-35-36t35-36l88-1z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1290 1466-42-102q-102-22-224-22-121 0-222 22l-42 101q124-31 264-31 138 0 266 32z" display="block"/>
+  <path style="color:black;" d="m1206 1260-29-70v-27q-76-11-153-11-75 0-152 11l-1 27-27 70q85-15 180-15 96 0 182 15z" display="block"/>
+  <path style="color:black;" d="m1171 1638q-40-30-80-95h-32q0 49 23 95h89z" display="block"/>
+  <path style="color:black;" d="m965 1638q23-49 23-95h-32q-39 64-81 95h90z" display="block"/>
+  <path style="color:black;" d="m987 912v85q0 37 37 37t37-37v-86h90q35 0 35-36t-35-36h-90v-90q0-37-37-37t-37 37v90h-88q-35 0-35 36t35 36l88 1z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/bk.svg b/public/images/pieces/bk.svg
new file mode 100644 (file)
index 0000000..f3936d1
--- /dev/null
@@ -0,0 +1,12 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1060 1261q172 3 282 17t198 33q55-54 122-103t94-84q48-65 48-162 0-89-43-149-77-113-235-113-92 0-192 40-91 36-132 78-85 82-124 216-15 46-16 117t-2 110z" display="block"/>
+  <path style="color:black;" d="m988 1260q0-40-2-110t-15-118q-41-134-124-216-43-42-132-78-102-40-193-40-158 0-234 113-43 60-43 150 0 98 48 161 25 36 96 89t120 98q87-19 196-33t283-16z" display="block"/>
+  <path style="color:black;" d="m1024 1009q7-28 12-39 10-39 23-66 6-17 17-39t25-52q8-17 17-41t18-49q8-20 8-43 0-49-35-83t-85-35q-119 0-119 119 0 23 8 43 22 65 34 90 13 29 24 51t19 40q13 33 22 66 2 6 12 38z" display="block"/>
+ </g>
+ <g fill-rule="nonzero">
+  <path style="color:black;" d="m1133 865q0 29 6 82t21 84q37 81 106 150 20 20 86 54 65 32 139 32 56 0 111-19t84-60q25-34 25-110 0-60-49-112-32-33-69-66t-71-79q-58 20-161 31t-228 13zm-73-78q172-3 282-17t198-33q55 54 122 103t94 84q48 65 48 162 0 89-43 149-77 113-235 113-92 0-192-40-91-36-132-78-85-82-124-216-15-46-16-117t-2-110zm458-173q-184 51-490 51-308 0-496-52l15-101q189 49 481 49 291 0 474-48l16 101zm26-299l-30 118q-195 45-490 45-292 0-488-45l-32-119q190 58 521 58 159 0 295-16t224-41zm-1081 207l-33 187q-1 0-3 4-5 7-28 18t-55 40q-44 37-68 60t-45 50q-61 84-68 203-10 115 93 229 104 114 281 107 66-4 155-32 29-12 59-23t61-24q16-8 28-16-5 21-5 42 0 78 55 133t134 56q78 0 133-55t55-133q0-16-4-42 14 9 27 15 46 20 121 47 86 29 155 33 177 8 280-107 101-114 94-229-8-119-69-203-20-27-45-50t-67-60q-33-28-56-39t-27-19q-1-2-2-3t-1-2l-32-188 66-247q-50-45-224-74t-402-29q-232 0-408 30t-221 77l66 244zm525 266q0 40-2 110t-15 118q-41 134-124 216-43 42-132 78-102 40-193 40-158 0-234-113-43-60-43-150 0-98 48-161 25-36 96-89t120-98q87 19 196 33t283 16zm36 251q7 28 12 39 10 39 23 66 6 17 17 39t25 52q8 17 17 41t18 49q8 20 8 43 0 49-35 83t-85 35q-119 0-119-119 0-23 8-43 22-65 34-90 13-29 24-51t19-40q13-33 22-66 2-6 12-38zm35 520h-71v131h-83q-34 0-34 33v1q0 33 34 33h83v85q0 35 36 35 35 0 35-35v-85h86q33 0 33-33v-1q0-33-33-33l-85-1-1-130zm-147-694q-125-2-228-13t-161-31q-30 37-69 74t-70 71q-50 51-50 112 0 75 25 110 27 40 83 59t113 20q72 0 138-32 65-34 86-54 68-69 106-150 13-30 19-83t8-83zm112 345q-2 10-5 17-6 20-10 29-3 7-8 17t-10 23q-3 7-7 18t-8 22q-3 9-3 19 0 53 51 53 53 0 53-52 0-13-4-19-14-38-15-41-15-30-19-39-7-16-9-29-3-6-4-10t-2-8z" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+  <path style="color:black;" d="m1518 1434q-184-51-490-51-308 0-496 52l15 101q189-49 481-49 291 0 474 48l16-101z" display="block" fill="#fff"/>
+  <path style="color:black;" d="m1544 1733-30-118q-195-45-490-45-292 0-488 45l-32 119q190-58 521-58 159 0 295 16t224 41z" display="block" fill="#fff"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/bn.svg b/public/images/pieces/bn.svg
new file mode 100644 (file)
index 0000000..261eec4
--- /dev/null
@@ -0,0 +1,11 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m490 683q4 9 13 27 17 42 17 50-2 28-29 28-20 0-47-57-4-8-12-14-27-28 8-47 32-19 50 13zm590 371q70 92 69 205-4 33-38 33-46 0-36-34 3-55-11-91-23-57-51-85-15-30 18-44 32-15 49 16zm-261 488q-5 36 2 78-60-12-113-56-32-17-15-47 17-31 47-10 21 11 38 20t41 15zm937-1268q-1 0 2 54t3 118q1 125 0 258t-36 267q-34 128-75 218t-89 157q-72 108-196 183t-259 98q4-23 3-47t0-46q97-33 183-82t126-106q48-66 89-156t75-219q34-133 35-266t1-259q0-63-3-117t0-55h141zm-677 1423q157-10 291-81t228-182q66-78 124-188t94-233q40-143 50-300t11-292v-218t-155 0-404 0h-671q-9 0-9 49t7 79q4 24 19 68t50 107q16 32 76 93t138 143q45 46 70 116t22 127q-37-30-81-49-212-76-307-220-7-9-45-81-20-38-34-52-19-19-55-21-56-3-87 54-42-12-75-10-56 21-81 45-51 51-66 102t-16 110q0 84 104 222 122 159 130 242 0 36 7 81 6 31 25 60 13 20 17 27t17 23q9 12 15 18t15 18q11 13 28 30-53 146-43 301 199-71 334-223 33 113 130 183 80-56 127-148zm-675-836q29 20 6 48-24 23-53 4-61-40-65-105 1-33 39-31 36 3 35 37 8 32 38 47zm252 498q22 11 22 11 30 12 19 44-12 30-46 20-118-43-163-158-7-33 24-45 31-10 42 22 8 17 12 22 11-9 29-12 61-10 71 54 3 22-10 42z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m490 1365q4-9 13-27 17-42 17-50-2-28-29-28-20 0-47 57-4 8-12 14-27 28 8 47 32 19 50-13z" display="block"/>
+  <path style="color:black;" d="m1080 994q70-92 69-205-4-33-38-33-46 0-36 34 3 55-11 91-23 57-51 85-15 30 18 44 32 15 49-16z" display="block"/>
+  <path style="color:black;" d="m819 506q-5-36 2-78-60 12-113 56-32 17-15 47 17 31 47 10 21-11 38-20t41-15z" display="block"/>
+  <path style="color:black;" d="m1756 1774q-1 0 2-54t3-118q1-125 0-258t-36-267q-34-128-75-218t-89-157q-72-108-196-183t-259-98q4 23 3 47t0 46q97 33 183 82t126 106q48 66 89 156t75 219q34 133 35 266t1 259q0 63-3 117t0 55h141z" display="block"/>
+  <path style="color:black;" d="m404 1187q29-20 6-48-24-23-53-4-61 40-65 105 1 33 39 31 36-3 35-37 8-32 38-47z" display="block"/>
+  <path style="color:black;" d="m656 689q22-11 22-11 30-12 19-44-12-30-46-20-118 43-163 158-7 33 24 45 31 10 42-22 8-17 12-22 11 9 29 12 61 10 71-54 3-22-10-42z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/bp.svg b/public/images/pieces/bp.svg
new file mode 100644 (file)
index 0000000..3eaa9f5
--- /dev/null
@@ -0,0 +1,3 @@
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1024 205h-540q-40 100-40 209 0 185 105 332t270 210q-71 33-115 99t-45 151q0 105 70 182t172 89q-81 61-81 161 0 84 59 144t145 60q84 0 144-60t60-144q0-100-81-161 102-12 172-89t70-182q0-84-45-150t-116-100q165-63 270-210t105-332q0-108-39-209h-540z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+</svg>
diff --git a/public/images/pieces/bq.svg b/public/images/pieces/bq.svg
new file mode 100644 (file)
index 0000000..49bfbe3
--- /dev/null
@@ -0,0 +1,8 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1588 793q-83 30-233 49t-333 20q-178 0-326-18t-233-49l50-91q84 25 218 36t293 11q159 0 294-11t219-37l51 90zm226 668q-57 0-97 39t-40 97q0 56 40 96t97 41q56 0 96-40t40-97q0-57-40-96t-96-40zm-1578 0q-57 0-96 39t-40 97q0 56 39 96t97 41q57 0 97-40t40-97q0-57-40-96t-97-40zm1208 110q-57 0-96 39t-40 97q0 56 39 96t97 40q57 0 97-40t40-96q0-57-40-96t-97-40zm-840 0q-57 0-97 39t-40 97q0 56 40 96t97 40q56 0 96-40t40-96q0-57-40-96t-96-40zm1036-1288q-49-43-220-72t-394-29q-227 0-399 30t-217 75l63 240-28 157-88 153-85 622 49 19 274-462 6 550 68 12 209-553 112 595h69l112-593 207 551 69-12 6-550 275 463 47-22-83-619-89-153-28-159 65-243zm-96 32l-30 118q-195 45-490 45-292 0-488-45l-32-119q190 58 521 58 159 0 295-16t224-41zm-26 299q-184 51-490 51-308 0-496-52l15-101q189 49 481 49 291 0 474-48l16 101zm-494 1007q-57 0-96 40t-40 97q0 56 39 96t97 40q56 0 96-40t41-96q0-57-40-97t-97-40z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1588 1255q-83-30-233-49t-333-20q-178 0-326 18t-233 49l50 91q84-25 218-36t293-11 294 11 219 37l51-90z" display="block"/>
+  <path style="color:black;" d="m1544 1733-30-118q-195-45-490-45-292 0-488 45l-32 119q190-58 521-58 159 0 295 16t224 41z" display="block"/>
+  <path style="color:black;" d="m1518 1434q-184-51-490-51-308 0-496 52l15 101q189-49 481-49 291 0 474 48l16-101z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/br.svg b/public/images/pieces/br.svg
new file mode 100644 (file)
index 0000000..c95631c
--- /dev/null
@@ -0,0 +1,10 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1161 1706h170v137h274v-375l-222-171v-478l170-170v-205h153v-239h-1365v239h153v205l171 170v478l-222 171v375h273v-137h171v137h274v-137zm-597-1246v-102h920v102h-920zm460 1092h-512v-46l73-55h879l71 55v46h-511zm0-169h-350l60-47v-57h580v57l60 47h-350zm0-546h-290v-46l-60-58h700l-60 58v46h-290zm0-172h-414l-46-43v-58h920v58l-46 43h-414z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m564 1588v102h920v-102h-920z" display="block"/>
+  <path style="color:black;" d="m1024 496h-512v46l73 55h879l71-55v-46h-511z" display="block"/>
+  <path style="color:black;" d="m1024 665h-350l60 47v57h580v-57l60-47h-350z" display="block"/>
+  <path style="color:black;" d="m1024 1211h-290v46l-60 58h700l-60-58v-46h-290z" display="block"/>
+  <path style="color:black;" d="m1024 1383h-414l-46 43v58h920v-58l-46-43h-414z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/new/Chess_Alt26.svg b/public/images/pieces/new/Chess_Alt26.svg
new file mode 100644 (file)
index 0000000..beeaaea
--- /dev/null
@@ -0,0 +1,25 @@
+<!-- Created with Inkscape (http://www.inkscape.org/) -->\r\r
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="26" width="26" version="1.0" xmlns:cc="http://creativecommons.org/ns#" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:dc="http://purl.org/dc/elements/1.1/">\r\r
+ <metadata>\r\r
+  <rdf:RDF>\r\r
+   <cc:Work rdf:about="">\r\r
+    <dc:format>image/svg+xml</dc:format>\r\r
+    <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>\r\r
+    <dc:title/>\r\r
+   </cc:Work>\r\r
+  </rdf:RDF>\r\r
+ </metadata>\r\r
+ <g transform="matrix(0.75757574,0,0,0.75757574,2.8791515,-7.9393932)">\r\r
+  <path stroke-linejoin="miter" d="m14.44,29.5c0.222,1.68-3.09,4.06-4.5,5-1.73,1.16-1.74,2.7-3,2.5-0.602-0.545,0.817-2.02,0-2-0.58,0,0.19,1.1-0.5,1.5-0.58,0-2.5,0.4-2.5-2.5,0-1.2,3.5-6.5,3.5-6.5s0.934-1.08,1-2c-0.419-0.575-0.258-1.48,0-2,0.365-0.731,1.5,1.5,1.5,1.5h1s0.5-1.5,1.5-2c0.517-0.258,0.5,2,0.5,2,6.07,0.578,9.29,4.37,9,16.5h-12.5c0-4.9,4.8-3.7,4.5-10.5" fill-rule="evenodd" stroke="#000" stroke-linecap="round" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="1.31999993" fill="#FFF"/>\r\r
+  <path fill="#000" d="m9,23.5a0.5,0.5,0,1,1,-1,0,0.5,0.5,0,1,1,1,0z" transform="translate(-3.4999999,10)"/>\r\r
+  <path fill="#000" d="m9.6058,30.28a1.0281,1.4729,30,0,1,-1.7807,-1.028,1.0281,1.4729,30,0,1,1.7807,1.028z"/>\r\r
+ </g>\r\r
+ <g transform="translate(0,-4)">\r\r
+  <path stroke-linejoin="round" d="m18,18,4-8-4,4,0-6-3,5.125-2-5-2,5l-3-5.125v6l-4-4,3,8s2.0349-2.5,6-2.5,5,2.5,5,2.5z" fill-rule="evenodd" stroke="#000" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="0.80000001" fill="#FFF"/>\r\r
+  <path id="path3804" stroke-linejoin="miter" d="m5.5,10a1.5,1.5,0,0,1,-3,0,1.5,1.5,0,1,1,3,0z" stroke-dashoffset="0" stroke="#000" stroke-linecap="butt" stroke-miterlimit="4" stroke-dasharray="none" stroke-width="0.75" fill="#FFF"/>\r\r
+  <use xlink:href="#path3804" transform="translate(4,-2)" height="26" width="26" y="0" x="0"/>\r\r
+  <use xlink:href="#path3804" transform="translate(9,-2)" height="26" width="26" y="0" x="0"/>\r\r
+  <use xlink:href="#path3804" transform="matrix(-1,0,0,1,26,0)" height="26" width="26" y="0" x="0"/>\r\r
+  <use xlink:href="#path3804" transform="matrix(-1,0,0,1,22,-2)" height="26" width="26" y="0" x="0"/>\r\r
+ </g>\r\r
+</svg>\r\r
diff --git a/public/images/pieces/new/Chess_Gdt45.svg b/public/images/pieces/new/Chess_Gdt45.svg
new file mode 100644 (file)
index 0000000..04978c8
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">\r
+<g>\r
+  <title>Giraffe</title>\r
+  <g style="opacity:1; fill:none; fill-opacity:1; fill-rule:evenodd; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">\r
+    <g stroke="#000000" stroke-dashoffset="0">\r
+      <path id="Hor_1" d="m17.6,4.8l3,0"/>\r
+      <path id="Ver_1" d="m19.2,9.9l0,-7.7"/>\r
+      <path id="Head" d="m39.5,40.1003l0,-5.478001c-6.243401,-2.459599 -4.459599,-20.018399 -8.919201,-24.117703c1.059601,-1.09367 4.459602,-2.45955 1.783901,-3.279408c-5.351601,-1.63971 -3.567801,0 -7.135401,1.63972c-3.567699,0 -10.703099,-3.27943 -12.486899,6.55879c-1.7838,3.279499 -5.35153,3.279499 -7.13536,6.558897c-1.12738,2.066 1.78383,6.558805 7.13536,1.6397c5.351501,0 8.9192,0 10.703,-3.2794c1.783899,3.2794 4.567699,4.3603 4.567699,20.757404l11.4869,0l0,-1z" style="fill:#000000;"/>\r
+      <path id="Hor_2" d="m21.1,5.9l3,0"/>\r
+      <path id="Ver_2" d="m22.7,11l0,-7.7"/>\r
+    </g>\r
+    <path id="Eye" d="m16.37441,14.57421a0.433,1.299 0 1 1 -0.866,-0.5a0.433,1.299 0 1 1 0.866,0.5z" fill="#ffffff" stroke="#ffffff"/>\r
+    <path id="Dot_1" d="m31.1,22.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#ffffff" stroke="#ffffff"/>\r
+    <path id="Dot_2" d="m33.3,30.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#ffffff" stroke="#ffffff"/>\r
+    <path id="Dot_3" d="m37.1,36.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#ffffff" stroke="#ffffff"/>\r
+  </g>\r
+</g>\r
+</svg>\r
diff --git a/public/images/pieces/new/Chess_Gll45.svg b/public/images/pieces/new/Chess_Gll45.svg
new file mode 100644 (file)
index 0000000..6011209
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">\r
+<g>\r
+  <title>Giraffe</title>\r
+  <g style="opacity:1; fill:none; fill-opacity:1; fill-rule:evenodd; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">\r
+    <rect x="0" y="0" width="45" height="45" style="fill:#ffce9e; stroke:none;"/>\r
+    <g stroke="#000000" stroke-dashoffset="0">\r
+      <path id="Hor_1" d="m17.6,4.8l3,0"/>\r
+      <path id="Ver_1" d="m19.2,9.9l0,-7.7"/>\r
+      <path id="Head" d="m39.5,40.1003l0,-5.478001c-6.243401,-2.459599 -4.459599,-20.018399 -8.919201,-24.117703c1.059601,-1.09367 4.459602,-2.45955 1.783901,-3.279408c-5.351601,-1.63971 -3.567801,0 -7.135401,1.63972c-3.567699,0 -10.703099,-3.27943 -12.486899,6.55879c-1.7838,3.279499 -5.35153,3.279499 -7.13536,6.558897c-1.12738,2.066 1.78383,6.558805 7.13536,1.6397c5.351501,0 8.9192,0 10.703,-3.2794c1.783899,3.2794 4.567699,4.3603 4.567699,20.757404l11.4869,0l0,-1z" style="fill:#ffffff;"/>\r
+      <path id="Hor_2" d="m21.1,5.9l3,0"/>\r
+      <path id="Ver_2" d="m22.7,11l0,-7.7"/>\r
+    </g>\r
+    <path id="Eye" d="m16.37441,14.57421a0.433,1.299 0 1 1 -0.866,-0.5a0.433,1.299 0 1 1 0.866,0.5z" fill="#000000" stroke="#000000"/>\r
+    <path id="Dot_1" d="m31.1,22.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#000000" stroke="#000000"/>\r
+    <path id="Dot_2" d="m33.3,30.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#000000" stroke="#000000"/>\r
+    <path id="Dot_3" d="m37.1,36.5a1.73,2.5 0 1 1 -3.46,0a1.73,2.5 0 1 1 3.46,0z" fill="#000000" stroke="#000000"/>\r
+  </g>\r
+</g>\r
+</svg>\r
diff --git a/public/images/pieces/new/Chess_Ult45.svg b/public/images/pieces/new/Chess_Ult45.svg
new file mode 100644 (file)
index 0000000..644d6e8
--- /dev/null
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>\r
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">\r
+<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="45" height="45">\r
+ <g>\r
+  <title>Unicorn</title>\r
+  <g id="Head" style="opacity:1; fill:none; fill-opacity:1; fill-rule:evenodd; stroke:#000000; stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round; stroke-miterlimit:4; stroke-dasharray:none; stroke-opacity:1;">\r
+    <path id="Neck" d="M 22,10 C 32.5,11 38.5,18 38,39 L 15,39 C 15,30 25,32.5 23,18" style="fill:#ffffff; stroke:#000000;"/>\r
+   <path id="Face" d="m24,18c0.38,2.91 -5.55,7.37 -8,9c-3,2 -2.82,4.34 -5,4c-1.042,-0.94 1.41,-3.04 0,-3c-1,0 0.19,1.23 -1,2c-1,0 -4,1 -4,-4c0,-2 6,-12 6,-12c0,0 -7.5275,-6.475 -7.0413,-7.15c0.4863,-0.675 8.9863,4.45 9.0413,3.65c-0.73,-0.994 -0.5,-2 -0.5,-3c1,-1 3,2.5 3,2.5l2,0c0,0 0.78,-1.992 2.5,-3c1,0 1,3 1,3" style="fill:#ffffff; stroke:#000000;"/>\r
+    <path id="Nose" d="M 9.5 25.5 A 0.5 0.5 0 1 1 8.5,25.5 A 0.5 0.5 0 1 1 9.5 25.5 z" style="fill:#000000; stroke:#000000;"/>\r
+    <path id="Eye" d="M 15 15.5 A 0.5 1.5 0 1 1  14,15.5 A 0.5 1.5 0 1 1  15 15.5 z" transform="matrix(0.866,0.5,-0.5,0.866,9.693,-5.173)" style="fill:#000000; stroke:#000000;"/>\r
+  </g>\r
+ </g>\r
+</svg>\r
diff --git a/public/images/pieces/new/Chess_Zdl45.svg b/public/images/pieces/new/Chess_Zdl45.svg
new file mode 100644 (file)
index 0000000..c924f0b
--- /dev/null
@@ -0,0 +1,141 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="45"
+   height="45"
+   id="svg3958"
+   sodipodi:docname="Chess Zdl45.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata3964">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3962" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1600"
+     inkscape:window-height="837"
+     id="namedview3960"
+     showgrid="false"
+     inkscape:zoom="10.488889"
+     inkscape:cx="29.513802"
+     inkscape:cy="29.471064"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3958" />
+  <rect
+     x="0"
+     y="0"
+     width="45"
+     height="45"
+     style="fill:#ffce9e; stroke:none;"
+     id="rect3956" />
+  <g
+     transform="translate(0.48241377,-0.5)"
+     id="g4115">
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path3491"
+       d="m 22,10 c 10.5,1 16.5,8 16,29 H 15 c 0,-9 10,-6.5 8,-21"
+       style="fill:#2b2b3c;fill-opacity:1;fill-rule:evenodd;stroke:#303042;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccccccccccc"
+       id="path3495"
+       d="m 24,18 c 0.384461,2.911278 -5.552936,7.368624 -8,9 -3,2 -2.819198,4.342892 -5,4 -1.04172,-0.944016 1.413429,-3.037549 0,-3 -1,0 0.187332,1.231727 -1,2 -1,0 -4.0031608,0.999999 -4,-4 0,-2 6,-12 6,-12 0,0 1.885866,-1.902129 2,-3.5 -0.726047,-0.994369 -0.5,-2 -0.5,-3 1,-1 3,2.5 3,2.5 h 2 c 0,0 0.781781,-1.9919255 2.5,-3 1,0 1,3 1,3"
+       style="fill:#2b2b3c;fill-opacity:1;fill-rule:evenodd;stroke:#303042;stroke-width:1px;stroke-linecap:round;stroke-linejoin:round;stroke-opacity:1" />
+    <circle
+       r="0.5"
+       cy="23.5"
+       cx="8.5"
+       transform="translate(0.5,2)"
+       id="path3499"
+       style="opacity:1;fill:#2b2b3c;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <ellipse
+       ry="1.5"
+       rx="0.5"
+       cy="15.5"
+       cx="14.5"
+       transform="rotate(30.000012,14.500009,15.499986)"
+       id="path3501"
+       style="opacity:1;fill:#2b2b3c;fill-opacity:1;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccsccccscc"
+       id="path8049"
+       d="m 24.55,10.4 -0.3,1.1 0.55,0.1 c 3.101459,0.477147 6.323526,2.234204 8.575,6.49375 C 35.626474,22.353296 36.297157,29.05687 35.8,39 l -0.05,0.5 H 37.5 V 39 C 38.002843,28.94313 36.623526,22.146704 34.25,17.65625 31.876474,13.165796 28.461041,11.022853 25.0625,10.5 Z"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:1;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path2818"
+       d="m 14.567771,38.459879 c 0.13635,-1.796208 0.558844,-3.152428 1.384569,-4.444516 0.233128,-0.364797 1.312337,-1.579372 2.398243,-2.699058 1.994197,-2.056232 2.893864,-3.226759 3.454584,-4.494646 0.446573,-1.009784 0.799401,-2.508009 0.890245,-3.78028 l 0.07945,-1.11275 -1.108514,1.075131 c -1.509002,1.46356 -2.57691,2.350841 -4.421012,3.673239 -1.700047,1.219096 -2.544384,2.006507 -3.665008,3.417912 -0.775227,0.976384 -1.421866,1.388405 -2.18696,1.393473 -0.575285,0.0038 -0.855457,-0.176834 -1.012077,-0.652545 l -0.134066,-0.40721 -1.0319639,0.04174 C 7.9615845,30.521081 7.3792222,30.361435 6.7525106,29.795239 6.1336101,29.236099 5.7610606,28.34997 5.6181745,27.09716 5.478446,25.872035 5.5914562,25.271009 6.2522413,23.724978 7.4052529,21.02729 11.111158,14.365763 12.223638,12.991129 c 0.361652,-0.446875 0.803261,-1.12024 0.981352,-1.496367 0.321358,-0.678706 0.322164,-0.68814 0.106827,-1.25 -0.119336,-0.3113731 -0.24652,-1.0767335 -0.28263,-1.7008009 -0.06502,-1.1237006 -0.06232,-1.137293 0.279605,-1.40625 0.189893,-0.1493702 0.502052,-0.2715821 0.693686,-0.2715821 0.498896,0 1.319417,0.6731881 2.100897,1.7236592 l 0.670536,0.9013408 h 0.733173 0.733173 l 0.270503,-0.53125 c 0.148777,-0.2921875 0.677944,-0.9390625 1.175928,-1.4375 0.781557,-0.7822703 0.965687,-0.90625 1.345925,-0.90625 0.33503,0 0.515317,0.088914 0.752972,0.3713508 0.304723,0.3621418 0.58282,1.3000334 0.586667,1.9785518 0.0029,0.5080395 0.12709,0.6173638 0.810586,0.7134464 6.88235,0.967487 11.352047,4.976401 13.517699,12.124151 1.123152,3.706976 1.627873,7.687946 1.755158,13.84375 l 0.07948,3.84375 h -0.500364 -0.500362 l 0.06018,-3.126764 C 37.71967,29.867039 37.027323,24.699753 35.44664,20.333049 33.737003,15.6101 30.713269,12.258466 26.998148,10.968382 c -0.532334,-0.184853 -2.215573,-0.602253 -2.428696,-0.602253 -0.08352,0 -0.32899,1.015984 -0.268939,1.113148 0.03671,0.0594 0.33074,0.147593 0.653394,0.195978 2.43577,0.365266 5.129133,1.935823 6.703427,3.90891 3.061731,3.837315 4.212184,8.694398 4.211846,17.781964 -7.5e-5,2.028125 -0.03645,4.235937 -0.08084,4.90625 l -0.08071,1.21875 H 25.098558 14.489486 l 0.07828,-1.03125 z M 9.6885199,26.18431 c 0.6200241,-0.620024 0.1806775,-1.693181 -0.6931819,-1.693181 -0.5138873,0 -1,0.486112 -1,1 0,0.513887 0.4861127,1 1,1 0.2435466,0 0.4997771,-0.113414 0.6931819,-0.306819 z m 4.6625311,-9.016105 c 0.720688,-0.42992 1.519287,-1.842801 1.519287,-2.687922 0,-0.482012 -0.458393,-0.901188 -0.873776,-0.799022 -0.470815,0.115799 -1.090962,0.77835 -1.506066,1.609047 -0.434872,0.870256 -0.474443,1.471536 -0.120158,1.825821 0.301661,0.301661 0.54102,0.314371 0.980713,0.05208 z"
+       style="fill:#000000" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path3787"
+       d="m 20,38 c 5,-5 11.375,-5.625 16.375,-6.625 l 0.125,0.75 C 31.5,33.125 25.75,34 21.75,38 Z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path4301"
+       d="m 36.25,28.5 c -5.54684,0.614372 -12.711319,1.059578 -18.25,5.25 2.125,-2.625 2.823017,-2.541667 3.625,-3.875 4,-1 9.188096,-2.067905 14.375,-2.875 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path4303"
+       d="M 23.75,25.75 C 29.759822,24.806647 31.895381,23.766153 35,23 v -1 c -3.365763,0.834839 -6.665102,2.155386 -11,2.5 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path4311"
+       d="M 36.5,35.625 C 32.65337,35.962561 30.888877,36.495727 28.625,38 l 3.125,-0.125 c 2.22881,-1.603573 3.356592,-1.372098 4.625,-1.375 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path4313"
+       d="m 33.125,17.75 c -1.651212,1.497849 -5.120762,2.268362 -8.375,3.125 l 0.125,-0.75 c 2.192276,-0.757978 2.842349,0.156524 7.5,-3.375 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path4317"
+       d="m 25.125,11.25 -1.75,2.25 0.375,-2.625 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path4319"
+       d="m 30,13.375 c -2.647892,2.504117 -2.719417,2.4805 -5.25,3.375 1.857607,-1.621366 2.685484,-2.344089 3.875,-4.75 z"
+       style="fill:#ffffff;fill-opacity:1;stroke:#ffffff;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/public/images/pieces/new/Chess_Zll45.svg b/public/images/pieces/new/Chess_Zll45.svg
new file mode 100644 (file)
index 0000000..35149c0
--- /dev/null
@@ -0,0 +1,151 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   width="45"
+   height="45"
+   id="svg3958"
+   sodipodi:docname="Chess Zll45.svg"
+   inkscape:version="0.92.1 r15371">
+  <metadata
+     id="metadata3964">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <defs
+     id="defs3962" />
+  <sodipodi:namedview
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1"
+     objecttolerance="10"
+     gridtolerance="10"
+     guidetolerance="10"
+     inkscape:pageopacity="0"
+     inkscape:pageshadow="2"
+     inkscape:window-width="1600"
+     inkscape:window-height="837"
+     id="namedview3960"
+     showgrid="false"
+     inkscape:zoom="5.2444444"
+     inkscape:cx="-10.010593"
+     inkscape:cy="22.5"
+     inkscape:window-x="-8"
+     inkscape:window-y="-8"
+     inkscape:window-maximized="1"
+     inkscape:current-layer="svg3958" />
+  <rect
+     x="0"
+     y="0"
+     width="45"
+     height="45"
+     style="fill:#ffce9e; stroke:none;"
+     id="rect3956" />
+  <g
+     transform="matrix(1.0140398,0,0,1.0140398,0.17629315,-0.8229154)"
+     id="g3930">
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path3491"
+       d="m 22,10 c 10.5,1 16.5,8 16,29 H 15 c 0,-9 10,-6.5 8,-21"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#303042;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csccccccccccc"
+       id="path3495"
+       d="m 24,18 c 0.384461,2.911278 -5.552936,7.368624 -8,9 -3,2 -2.819198,4.342892 -5,4 -1.04172,-0.944016 1.413429,-3.037549 0,-3 -1,0 0.187332,1.231727 -1,2 -1,0 -4.0031608,0.999999 -4,-4 0,-2 6,-12 6,-12 0,0 1.885866,-1.902129 2,-3.5 -0.726047,-0.994369 -0.5,-2 -0.5,-3 1,-1 3,2.5 3,2.5 h 2 c 0,0 0.781781,-1.9919255 2.5,-3 1,0 1,3 1,3"
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#303042;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <circle
+       r="0.5"
+       cy="23.5"
+       cx="8.5"
+       transform="translate(0.5,2)"
+       id="path3499"
+       style="opacity:1;fill:#2b2b3c;fill-opacity:1;stroke:#303042;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <ellipse
+       ry="1.5"
+       rx="0.5"
+       cy="15.5"
+       cx="14.5"
+       transform="rotate(30.000012,14.500009,15.499986)"
+       id="path3501"
+       style="opacity:1;fill:#2b2b3c;fill-opacity:1;stroke:#303042;stroke-width:1.50000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cc"
+       id="path8049"
+       d="M 37,39 C 38,19 31.5,11.5 25,10.5"
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#303042;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path2818"
+       d="m 13.570834,17.509658 c -0.902763,-0.33922 -0.850713,-1.577785 0.126899,-3.019655 0.259022,-0.38203 0.639424,-0.75084 0.928764,-0.900463 0.26888,-0.139044 0.789946,-0.125645 1.036362,0.02665 0.597382,0.369202 0.529851,1.444693 -0.163612,2.605681 -0.560458,0.938312 -1.387915,1.490886 -1.928413,1.287789 z"
+       style="fill:#000000" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path2820"
+       d="M 8.6106628,26.650703 C 7.7855415,26.356556 7.5163445,25.352081 8.0881125,24.700874 c 0.248293,-0.28279 0.5118814,-0.39612 0.9213178,-0.39612 0.6951161,0 1.1864037,0.491542 1.1864037,1.187018 0,0.567964 -0.279724,0.968758 -0.8056187,1.154304 -0.3293627,0.116206 -0.4643125,0.117007 -0.7795525,0.0046 v 0 z"
+       style="fill:#000000" />
+    <path
+       inkscape:connector-curvature="0"
+       id="path2822"
+       d="m 14.259946,39.164129 c 0.0061,-2.175316 0.467489,-3.804667 1.526174,-5.38916 0.517346,-0.774292 1.069421,-1.386038 2.879921,-3.191199 1.577588,-1.572935 2.241545,-2.445087 2.838645,-3.728749 0.474235,-1.019524 0.805064,-2.285137 0.935537,-3.578979 0.03452,-0.342354 0.05246,-0.632773 0.03986,-0.645376 -0.0126,-0.0126 -0.144428,0.108914 -0.292945,0.270037 -0.378145,0.410238 -1.895395,1.776092 -2.678801,2.4115 -0.880287,0.713987 -1.500918,1.179443 -2.665691,1.999195 -1.48269,1.043498 -1.860607,1.409752 -2.959708,2.868356 -0.862666,1.144835 -1.394058,1.499471 -2.320321,1.548517 -0.327714,0.01735 -0.627847,-6.25e-4 -0.76462,-0.04574 -0.260488,-0.08597 -0.640136,-0.498838 -0.697073,-0.758072 l -0.03913,-0.178137 -0.8861054,0.03757 C 8.4620061,30.814158 8.2105342,30.801275 7.883334,30.717688 6.6663902,30.406803 5.8657907,29.546146 5.5139862,28.170604 5.3533351,27.542464 5.2366643,26.308623 5.290438,25.806492 c 0.090143,-0.841745 0.5752779,-2.044241 1.8161799,-4.501738 0.897802,-1.778018 1.9943674,-3.782876 3.3415351,-6.10935 0.629801,-1.087628 1.003562,-1.653529 1.486059,-2.25 0.64103,-0.792453 1.261622,-1.864455 1.261622,-2.179309 0,-0.07331 -0.06665,-0.284443 -0.148108,-0.469189 -0.229468,-0.5204222 -0.289392,-0.9210441 -0.289392,-1.9347358 0,-1.0965953 0.05214,-1.2785655 0.439866,-1.5351503 0.386676,-0.2558905 0.926932,-0.2799111 1.402165,-0.062342 0.552086,0.2527534 1.411733,1.1355651 2.06262,2.1182015 l 0.238046,0.359375 h 0.584902 c 0.321695,0 0.584901,-0.023788 0.584901,-0.052863 0,-0.029075 0.195094,-0.3482588 0.433541,-0.7092984 0.486858,-0.7371631 1.209428,-1.4941701 1.815791,-1.9023301 0.338876,-0.2281061 0.45493,-0.2730086 0.705615,-0.2730086 0.840207,0 1.346119,0.7136149 1.578483,2.2265303 0.05742,0.3738458 0.113339,0.7113563 0.12427,0.7500231 0.01093,0.038667 0.183826,0.090048 0.384212,0.1141811 1.109824,0.133657 2.783989,0.5321304 3.958088,0.9420762 0.856099,0.298914 2.376217,1.043979 3.125,1.531675 2.830187,1.843352 4.892469,4.612939 6.323297,8.492011 1.2411,3.364705 1.949429,7.615837 2.177488,13.068503 0.06793,1.624124 0.08245,5.709986 0.0216,6.078125 l -0.03874,0.234375 H 26.468906 14.258334 l 0.0016,-0.578125 z m 22.341729,-2.75 c 0.04787,-1.938166 -0.0286,-4.583278 -0.186686,-6.45724 C 35.8658,23.446806 34.231641,18.381927 31.62328,15.105563 29.87953,12.915237 26.952257,11.464761 23.070834,10.867789 22.606771,10.796415 22.122435,10.72868 21.99453,10.717267 21.50961,10.673997 21.258645,10.337146 21.257965,9.7286364 21.257465,9.2992224 21.093221,8.213367 21.003331,8.045406 20.936751,7.9209996 20.913436,7.9341919 20.530815,8.3127732 20.06392,8.7747397 19.619212,9.3966874 19.297417,10.037747 c -0.333855,0.665086 -0.345708,0.66984 -1.723615,0.691368 -1.46866,0.02295 -1.425592,0.04193 -2.062817,-0.9093209 C 15.02649,9.0965377 14.3652,8.304754 14.245638,8.304754 c -0.04562,0 -0.05654,0.1744458 -0.03376,0.539551 0.02881,0.4617146 0.06736,0.6059349 0.267228,0.9997142 0.218087,0.4296658 0.231482,0.4881428 0.20212,0.8823238 -0.06251,0.839186 -0.628621,1.942052 -1.628297,3.172161 -1.262873,1.553975 -5.291276,8.993024 -6.0765343,11.221229 l -0.2304003,0.653771 0.035122,0.8125 c 0.063706,1.473763 0.4469433,2.317218 1.1943668,2.628646 0.3061981,0.127583 1.608565,0.146315 1.7544582,0.02524 0.063899,-0.05303 0.090998,-0.207742 0.091243,-0.520909 4.625e-4,-0.592951 0.095188,-0.902925 0.3491046,-1.142398 0.338758,-0.31949 1.016991,-0.400707 1.463047,-0.175195 0.372554,0.18835 0.608134,0.665197 0.533224,1.07932 -0.02291,0.126665 -0.180386,0.544833 -0.349942,0.92926 -0.328136,0.743975 -0.373689,0.933263 -0.20942,0.870228 0.05437,-0.02087 0.125314,-0.03794 0.157646,-0.03794 0.111508,0 0.622452,-0.51998 0.976441,-0.993707 1.018421,-1.362909 1.68749,-2.03382 2.823639,-2.831414 3.491498,-2.451083 5.782608,-4.507465 6.940862,-6.229761 0.466468,-0.693626 0.706092,-1.286565 0.735564,-1.820118 0.03155,-0.571076 0.104907,-0.777586 0.334252,-0.940894 0.374061,-0.266355 0.840001,-0.127845 1.077593,0.320336 0.219478,0.414013 0.04788,1.428673 -0.39764,2.351243 -0.241086,0.499234 -0.247223,0.528694 -0.247371,1.1875 -5.62e-4,2.498922 -0.419697,4.631699 -1.249823,6.359737 -0.668433,1.391448 -1.326059,2.227685 -3.442484,4.377459 -0.948039,0.962978 -1.89202,1.978271 -2.097734,2.256206 -0.727386,0.982755 -1.191051,2.091757 -1.369523,3.275653 -0.04925,0.326706 -0.08971,0.615104 -0.08991,0.640885 -1.88e-4,0.02578 4.679222,0.04687 10.398723,0.04687 h 10.399092 l 0.04516,-1.828125 v 0 z"
+       style="fill:#000000" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path2842"
+       d="m 29.125,38.5 c 4.4165,-3.861167 4.731206,-1.256265 8.75,-2.375 l -0.25,-1.5 c -5.397948,0.236411 -8.685171,1.26391 -12.375,4.125 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path3616"
+       d="m 20.25,38.625 c 5.09531,-5.317491 8.412271,-6.610725 17.25,-7.25 l -0.125,-1.25 C 32.618393,30.247775 22.47971,31.909466 17.5,39 Z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path3620"
+       d="M 23.5,24.25 C 28.011828,24.21622 31.290098,22.526732 36,22 c -0.375,-1.171285 -0.375,-2.316519 -0.75,-1.875 -2.71602,2.057443 -6.746333,1.937733 -11.875,3 -0.382887,-0.49777 0.20575,0.112079 0.125,1.125 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path3622"
+       d="m 24,20 c 3.75,-1.875 8.083333,-1.666667 9.5,-3.25 l -1.125,-1.375 c -0.949713,2.433548 -5.729817,2.431804 -8,3.875 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path3624"
+       d="M 30.625,13.25 27,14.625 l 2,-2.75 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="cccc"
+       id="path3632"
+       d="m 25.25,10.375 -1.375,2.75 -0.75,-3 c 4.612445,0.626274 1.36035,0.215695 2.125,0.25 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+    <path
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccc"
+       id="path3660"
+       d="m 36.75,25.25 c -4.368579,1.214754 -8.595337,2.57133 -14.25,2.5 l -4.375,4.75 c 4.074203,-2.614726 8.927769,-4.983336 19.25,-5.625 z"
+       style="fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1" />
+  </g>
+</svg>
diff --git a/public/images/pieces/new/Chess_adt45.svg b/public/images/pieces/new/Chess_adt45.svg
new file mode 100644 (file)
index 0000000..afc27f0
--- /dev/null
@@ -0,0 +1,156 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="45"
+   height="45"
+   id="svg3128"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   version="1.0"
+   sodipodi:docname="Chess_adt45.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs3130">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       id="perspective15" />
+    <inkscape:perspective
+       id="perspective12"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 22.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="4.0000002"
+     inkscape:cx="70.546042"
+     inkscape:cy="-5.7955825"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     height="45px"
+     width="45px"
+     inkscape:grid-points="true"
+     showgrid="true"
+     inkscape:window-width="960"
+     inkscape:window-height="1060"
+     inkscape:window-x="0"
+     inkscape:window-y="20"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       id="GridFromPre046Settings"
+       type="xygrid"
+       originx="0"
+       originy="0"
+       spacingx="0.5"
+       spacingy="0.5"
+       color="#0000ff"
+       empcolor="#0000ff"
+       opacity="0.2"
+       empopacity="0.4"
+       empspacing="5" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata3133">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="display:inline">
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000000000000000;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 36,36 C 32.614745,35.027671 25.885256,36.430821 22.5,34 C 19.114744,36.430821 12.385255,35.027671 9,36 C 9,36 7.354102,36.541507 6,38 C 6.677051,38.972328 7.645898,38.986164 9,38.5 C 12.385255,37.527672 19.114744,38.958493 22.5,37.5 C 25.885256,38.958493 32.614745,37.527672 36,38.5 C 37.354102,38.986164 38.322949,38.972328 39,38 C 37.645898,36.055343 36,36 36,36 z"
+       id="path4582"
+       sodipodi:nodetypes="ccccccccc" />
+    <path
+       style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000000000000000;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 30,32 C 27.5,34.5 17.5,34.5 15,32 C 14.5,30.5 15,30 15,30 L 30,30 C 30,30 30.5,30.5 30,32 z"
+       id="path4584"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 30,30 L 15,30"
+       id="path4590"
+       sodipodi:nodetypes="cc" />
+    <g
+       id="g3323"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.7654224,0,0,-0.7654224,37.205613,35.181827)"
+       style="fill:#000000;fill-opacity:1">
+      <path
+         sodipodi:nodetypes="cccc"
+         id="path3491"
+         d="M 22.028958,36 C 11.528958,35 5.5289585,28 6.0289585,7 L 29.028958,7 C 29.028958,16 19.028958,13.5 21.028958,28"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000000000000000;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="csccccccccccc"
+         id="path3495"
+         d="M 20.028958,28 C 19.644497,25.088722 25.581894,20.631376 28.028958,19 C 31.028958,17 30.848156,14.657108 33.028958,15 C 34.070678,15.944016 31.615529,18.037549 33.028958,18 C 34.028958,18 32.841626,16.768273 34.028958,16 C 35.028958,16 38.032119,15.000001 38.028958,20 C 38.028958,22 32.028958,32 32.028958,32 C 32.028958,32 30.143092,33.902129 30.028958,35.5 C 30.755005,36.494369 30.528958,37.5 30.528958,38.5 C 29.528958,39.5 27.528958,36 27.528958,36 L 25.528958,36 C 25.528958,36 24.747177,37.991926 23.028958,39 C 22.028958,39 22.028958,36 22.028958,36"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         transform="matrix(-1,0,0,-1,43.528958,44)"
+         d="M 9,23.5 A 0.5,0.5 0 0 1 8.5,24 0.5,0.5 0 0 1 8,23.5 0.5,0.5 0 0 1 8.5,23 0.5,0.5 0 0 1 9,23.5 Z"
+         sodipodi:ry="0.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="23.5"
+         sodipodi:cx="8.5"
+         id="path3499"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.50000000000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         transform="matrix(-0.866025,-0.5,0.5,-0.866025,34.336326,51.173394)"
+         d="M 15,15.5 A 0.5,1.5 0 0 1 14.5,17 0.5,1.5 0 0 1 14,15.5 0.5,1.5 0 0 1 14.5,14 0.5,1.5 0 0 1 15,15.5 Z"
+         sodipodi:ry="1.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="15.5"
+         sodipodi:cx="14.5"
+         id="path3501"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#ffffff;stroke-width:1.50000048000000000;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:nodetypes="cc"
+         id="path8049"
+         d="M 7.0289585,7 C 6.0289585,27 12.528958,34.5 19.028958,35.5"
+         style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+    <path
+       style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:#ffffff;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+       d="M 15,30 L 30,30"
+       id="path3369" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Layer 1#1"
+     style="display:inline" />
+</svg>
diff --git a/public/images/pieces/new/Chess_alt45.svg b/public/images/pieces/new/Chess_alt45.svg
new file mode 100644 (file)
index 0000000..b45ea50
--- /dev/null
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="45"
+   height="45"
+   id="svg3128"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   version="1.0"
+   sodipodi:docname="Chess_alt45.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs3130">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       id="perspective15" />
+    <inkscape:perspective
+       id="perspective12"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 22.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="2.0000001"
+     inkscape:cx="59.308779"
+     inkscape:cy="58.114787"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     height="45px"
+     width="45px"
+     inkscape:grid-points="true"
+     showgrid="false"
+     inkscape:window-width="960"
+     inkscape:window-height="1060"
+     inkscape:window-x="0"
+     inkscape:window-y="20"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       id="GridFromPre046Settings"
+       type="xygrid"
+       originx="0"
+       originy="0"
+       spacingx="0.5"
+       spacingy="0.5"
+       color="#0000ff"
+       empcolor="#0000ff"
+       opacity="0.2"
+       empopacity="0.4"
+       empspacing="5" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata3133">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="display:inline">
+    <path
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 36,36 C 32.614745,35.027671 25.885256,36.430821 22.5,34 C 19.114744,36.430821 12.385255,35.027671 9,36 C 9,36 7.354102,36.541507 6,38 C 6.677051,38.972328 7.645898,38.986164 9,38.5 C 12.385255,37.527672 19.114744,38.958493 22.5,37.5 C 25.885256,38.958493 32.614745,37.527672 36,38.5 C 37.354102,38.986164 38.322949,38.972328 39,38 C 37.645898,36.055343 36,36 36,36 z"
+       id="path4582"
+       sodipodi:nodetypes="ccccccccc" />
+    <path
+       style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 30,32 C 27.5,34.5 17.5,34.5 15,32 C 14.5,30.5 15,30 15,30 L 30,30 C 30,30 30.5,30.5 30,32 z"
+       id="path4584"
+       sodipodi:nodetypes="ccccc" />
+    <path
+       style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 30,30 L 15,30"
+       id="path4590"
+       sodipodi:nodetypes="cc" />
+    <g
+       id="g3323"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.7654224,0,0,-0.7654224,37.205613,35.181827)">
+      <path
+         sodipodi:nodetypes="cccc"
+         id="path3491"
+         d="M 22.028958,36 C 11.528958,35 5.5289585,28 6.0289585,7 L 29.028958,7 C 29.028958,16 19.028958,13.5 21.028958,28"
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="csccccccccccc"
+         id="path3495"
+         d="M 20.028958,28 C 19.644497,25.088722 25.581894,20.631376 28.028958,19 C 31.028958,17 30.848156,14.657108 33.028958,15 C 34.070678,15.944016 31.615529,18.037549 33.028958,18 C 34.028958,18 32.841626,16.768273 34.028958,16 C 35.028958,16 38.032119,15.000001 38.028958,20 C 38.028958,22 32.028958,32 32.028958,32 C 32.028958,32 30.143092,33.902129 30.028958,35.5 C 30.755005,36.494369 30.528958,37.5 30.528958,38.5 C 29.528958,39.5 27.528958,36 27.528958,36 L 25.528958,36 C 25.528958,36 24.747177,37.991926 23.028958,39 C 22.028958,39 22.028958,36 22.028958,36"
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         transform="matrix(-1,0,0,-1,43.528958,44)"
+         d="M 9,23.5 A 0.5,0.5 0 0 1 8.5,24 0.5,0.5 0 0 1 8,23.5 0.5,0.5 0 0 1 8.5,23 0.5,0.5 0 0 1 9,23.5 Z"
+         sodipodi:ry="0.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="23.5"
+         sodipodi:cx="8.5"
+         id="path3499"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         transform="matrix(-0.866025,-0.5,0.5,-0.866025,34.336326,51.173394)"
+         d="M 15,15.5 A 0.5,1.5 0 0 1 14.5,17 0.5,1.5 0 0 1 14,15.5 0.5,1.5 0 0 1 14.5,14 0.5,1.5 0 0 1 15,15.5 Z"
+         sodipodi:ry="1.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="15.5"
+         sodipodi:cx="14.5"
+         id="path3501"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.50000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:nodetypes="cc"
+         id="path8049"
+         d="M 7.0289585,7 C 6.0289585,27 12.528958,34.5 19.028958,35.5"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Layer 1#1"
+     style="display:inline" />
+</svg>
diff --git a/public/images/pieces/new/Chess_clt45.svg b/public/images/pieces/new/Chess_clt45.svg
new file mode 100644 (file)
index 0000000..fd0288d
--- /dev/null
@@ -0,0 +1,175 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="45"
+   height="45"
+   id="svg3128"
+   sodipodi:version="0.32"
+   inkscape:version="0.92.2 5c3e80d, 2017-08-06"
+   version="1.0"
+   sodipodi:docname="Chess_clt45.svg"
+   inkscape:output_extension="org.inkscape.output.svg.inkscape">
+  <defs
+     id="defs3130">
+    <inkscape:perspective
+       sodipodi:type="inkscape:persp3d"
+       inkscape:vp_x="0 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       id="perspective15" />
+    <inkscape:perspective
+       id="perspective12"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 22.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+    <inkscape:perspective
+       id="perspective14"
+       inkscape:persp3d-origin="22.5 : 15 : 1"
+       inkscape:vp_z="45 : 22.5 : 1"
+       inkscape:vp_y="0 : 1000 : 0"
+       inkscape:vp_x="0 : 22.5 : 1"
+       sodipodi:type="inkscape:persp3d" />
+  </defs>
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     gridtolerance="10000"
+     guidetolerance="10"
+     objecttolerance="10"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="8.0000004"
+     inkscape:cx="-4.1805949"
+     inkscape:cy="32.150177"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     height="45px"
+     width="45px"
+     inkscape:grid-points="true"
+     showgrid="false"
+     inkscape:window-width="960"
+     inkscape:window-height="1060"
+     inkscape:window-x="0"
+     inkscape:window-y="20"
+     inkscape:window-maximized="0">
+    <inkscape:grid
+       id="GridFromPre046Settings"
+       type="xygrid"
+       originx="0"
+       originy="0"
+       spacingx="0.5"
+       spacingy="0.5"
+       color="#0000ff"
+       empcolor="#0000ff"
+       opacity="0.2"
+       empopacity="0.4"
+       empspacing="5" />
+  </sodipodi:namedview>
+  <metadata
+     id="metadata3133">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Layer 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     style="display:inline">
+    <g
+       id="g3481"
+       transform="translate(0,-0.3093592)">
+      <path
+         sodipodi:nodetypes="cccc"
+         id="path3127"
+         d="M 34,35.130223 L 31,32.130223 L 14,32.130223 L 11,35.130223"
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <g
+         id="g3476">
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M 11,35.130223 L 11,40.130223 L 15,40.130223 L 15,38.130223 L 20,38.130223 L 20,40.130223 L 25,40.130223 L 25,38.130223 L 30,38.130223 L 30,40.130223 L 34,40.130223 L 34,35.130223"
+           id="path3129"
+           sodipodi:nodetypes="cccccccccccc" />
+        <path
+           style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+           d="M 31.552703,32.417761 L 31.552703,30.302822 L 13.447297,30.302822 L 13.447297,32.417761"
+           id="path3125"
+           sodipodi:nodetypes="cccc" />
+        <path
+           style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1px;stroke-linecap:round;stroke-linejoin:miter;stroke-opacity:1"
+           d="M 11,35.130223 L 34,35.130223"
+           id="path5175" />
+      </g>
+    </g>
+    <g
+       id="g3323"
+       inkscape:label="Layer 1"
+       transform="matrix(-0.7654224,0,0,-0.7654224,37.205613,35.181827)">
+      <path
+         sodipodi:nodetypes="cccc"
+         id="path3491"
+         d="M 22.028958,36 C 11.528958,35 5.5289585,28 6.0289585,7 L 29.028958,7 C 29.028958,16 19.028958,13.5 21.028958,28"
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         sodipodi:nodetypes="csccccccccccc"
+         id="path3495"
+         d="M 20.028958,28 C 19.644497,25.088722 25.581894,20.631376 28.028958,19 C 31.028958,17 30.848156,14.657108 33.028958,15 C 34.070678,15.944016 31.615529,18.037549 33.028958,18 C 34.028958,18 32.841626,16.768273 34.028958,16 C 35.028958,16 38.032119,15.000001 38.028958,20 C 38.028958,22 32.028958,32 32.028958,32 C 32.028958,32 30.143092,33.902129 30.028958,35.5 C 30.755005,36.494369 30.528958,37.5 30.528958,38.5 C 29.528958,39.5 27.528958,36 27.528958,36 L 25.528958,36 C 25.528958,36 24.747177,37.991926 23.028958,39 C 22.028958,39 22.028958,36 22.028958,36"
+         style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+      <path
+         transform="matrix(-1,0,0,-1,43.528958,44)"
+         d="M 9,23.5 A 0.5,0.5 0 0 1 8.5,24 0.5,0.5 0 0 1 8,23.5 0.5,0.5 0 0 1 8.5,23 0.5,0.5 0 0 1 9,23.5 Z"
+         sodipodi:ry="0.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="23.5"
+         sodipodi:cx="8.5"
+         id="path3499"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.5;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         transform="matrix(-0.866025,-0.5,0.5,-0.866025,34.336326,51.173394)"
+         d="M 15,15.5 A 0.5,1.5 0 0 1 14.5,17 0.5,1.5 0 0 1 14,15.5 0.5,1.5 0 0 1 14.5,14 0.5,1.5 0 0 1 15,15.5 Z"
+         sodipodi:ry="1.5"
+         sodipodi:rx="0.5"
+         sodipodi:cy="15.5"
+         sodipodi:cx="14.5"
+         id="path3501"
+         style="opacity:1;fill:#000000;fill-opacity:1;stroke:#000000;stroke-width:1.50000048;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+         sodipodi:type="arc" />
+      <path
+         sodipodi:nodetypes="cc"
+         id="path8049"
+         d="M 7.0289585,7 C 6.0289585,27 12.528958,34.5 19.028958,35.5"
+         style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1" />
+    </g>
+    <path
+       style="fill:none;fill-opacity:0.75000000000000000;fill-rule:evenodd;stroke:#000000;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
+       d="M 30,30 L 15,30"
+       id="path4590"
+       sodipodi:nodetypes="cc" />
+  </g>
+  <g
+     inkscape:groupmode="layer"
+     id="layer2"
+     inkscape:label="Layer 1#1"
+     style="display:inline" />
+</svg>
diff --git a/public/images/pieces/new/camel-animal-pet-desert-39f82768c72363eb.svg b/public/images/pieces/new/camel-animal-pet-desert-39f82768c72363eb.svg
new file mode 100644 (file)
index 0000000..233a4f5
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 52 52" xml:space="preserve"><path d="M47.751 21.077c-1.02-.79-2.14-.93-2.96-.88-.73-4.53-4.21-8.13-8.79-8.94-.1-2.4-1.67-4.42-3.99-5.03-1.71-.45-3.47-.11-4.84.94-1.3 1-2.08 2.49-2.15 4.11-3.55.82-6.55 4.43-8.02 8.39-.58-1.61-1.47-3.26-2.86-4.36-1.4-1.11-3.08-1.5-4.99-1.16-.48.08-.83.5-.83.98v3.3h-3.26a3.06 3.06 0 0 0-3.06 3.06c0 .82.32 1.59.89 2.16.57.58 1.34.9 2.17.9h3.01l-.05 4.47c-.02 1.25.46 2.42 1.33 3.31.88.89 2.05 1.38 3.3 1.38h4.98v8.68c0 1.98 1.61 3.58 3.59 3.58s3.59-1.6 3.59-3.58v-8.68h3.02v8.68c0 1.98 1.61 3.58 3.59 3.58 1.98 0 3.59-1.6 3.59-3.58v-8.68h2.75v8.68c0 1.98 1.61 3.58 3.59 3.58s3.58-1.6 3.58-3.58v-11.93l.01-.01v-8.27c.45-.01 1.06.07 1.59.48 1.13.87 1.63 2.96 1.43 6.03-.04.55.38 1.02.93 1.06h.07c.52 0 .96-.41.99-.93.25-3.82-.49-6.43-2.2-7.74zm-34.79-.09c-.19.18-.45.29-.71.29-.27 0-.52-.11-.71-.29-.18-.19-.29-.45-.29-.71 0-.27.11-.52.29-.71.37-.37 1.04-.37 1.42 0 .18.19.29.44.29.71 0 .26-.11.52-.29.71z"/><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description about="https://iconscout.com/legal#licenses" dc:title="camel,animal,pet,desert" dc:description="camel,animal,pet,desert" dc:publisher="Iconscout" dc:date="2017-11-11" dc:format="image/svg+xml" dc:language="en"><dc:creator><rdf:Bag><rdf:li>Dinosoft Labs</rdf:li></rdf:Bag></dc:creator></rdf:Description></rdf:RDF></metadata></svg>
\ No newline at end of file
diff --git a/public/images/pieces/new/camel-animal-pet-desert-3f04e77f40eba40d.svg b/public/images/pieces/new/camel-animal-pet-desert-3f04e77f40eba40d.svg
new file mode 100644 (file)
index 0000000..9a5ab39
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 52 52" xml:space="preserve"><path fill="#231F20" d="M37.9 27.1c-.4 4.4-.8 9.2-.1 13.6.2 1.4.3 3 1.5 4 2.9 2.4 5.4-.7 5.9-3.4.6-2.9.4-6 .6-8.9.2-3.7.8-7.8.4-11.6-.6-5.9-5.2-8.2-10.3-9.9-1.5-.5-2.2 1.9-.7 2.4 5.5 1.8 8.6 4.2 8.6 10.3 0 3.6-.4 7.1-.6 10.7-.1 1.3.3 3.4-.2 4.6.1 1.3-.8 1.9-2.7 1.8 0-.6-.1-1.3-.1-1.9-.9-3.3 0-8.2.3-11.6.1-1.7-2.5-1.7-2.6-.1z"/><path fill="#231F20" d="M36.5 11.7c-.3-1.4-.2-3.5-1.4-4.6-1-.9-3-1.4-4.3-1.6-3.6-.4-5.2 2.2-5.9 5.4-.4 1.6 2.1 2.2 2.4.7.5-2.1 1.2-4 3.8-3.5.8.2 2 .5 2.4 1.2.4.7.4 2.2.6 3 .3 1.7 2.7 1 2.4-.6z"/><path fill="#231F20" d="M25.4 10.4c-5.4 2.8-8.7 7.9-9.5 13.9.8-.1 1.6-.2 2.5-.3-1-2.8-.3-6.2-2.3-8.6-1.6-1.9-4-2.4-6.3-2-1.6.3-.9 2.7.7 2.4 5.4-1 4.4 5.6 5.6 8.8.5 1.4 2.3 1.1 2.5-.3.7-5.1 3.7-9.3 8.2-11.7 1.3-.8 0-3-1.4-2.2z"/><path fill="#231F20" d="M8.5 14.5c.1 1.3 0 2.6-.2 3.8-.1.7.2 1.3.9 1.5.6.2 1.4-.2 1.5-.9.2-1.5.3-3 .3-4.5-.1-1.6-2.6-1.6-2.5.1z"/><path fill="#231F20" d="M9.4 17.4c-2.3 0-8.7 0-8 3.8.2 1.2 1 3.5 2.3 3.8.7.2 1.6-.1 2.3-.2 1.1-.2 2.1-.4 3.2-.6 1.6-.3.9-2.7-.7-2.4-1 .2-2 .3-3 .5-.3 0-.8.2-1 .1-.1 0-.5-1.1-.5-1.3 0-.6.3-.5.9-.7l1.5-.3c1-.1 2.1-.2 3.1-.2 1.5 0 1.5-2.5-.1-2.5z"/><path fill="#231F20" d="M8 22.8c-1 3.3-2.7 8.7 1.2 11.1 1.7 1.1 5.2.5 7.1.4 3.9-.2 7.9-.5 11.8-.7 1.6-.1 1.6-2.6 0-2.5-4.2.2-8.3.5-12.5.7-2.4.1-5.2.4-6.1-2.3-.7-1.9.3-4.2.9-6.1.4-1.5-2-2.1-2.4-.6z"/><path fill="#231F20" d="M12.8 21.4c1.6 0 1.6-2.5 0-2.5s-1.7 2.5 0 2.5z"/><path fill="#231F20" d="M27.8 27.2c-.2 4.9-.8 10-.4 14.9.2 2.3 1.4 4.5 4.1 4.4 7.5-.5 4.2-14.3 4.6-18.7.1-1.6-2.4-1.6-2.5 0-.2 2.4 0 4.8.1 7.3.1 1.1.2 2.2.1 3.3 0 .8-.1 1.5-.2 2.3 0 1.7-1.2 2.2-3.6 1.5-.7-.9.1-5.4.2-6.6.1-2.8.2-5.6.3-8.3-.1-1.7-2.6-1.7-2.7-.1z"/><path fill="#231F20" d="M35.1 33.6h3.6c1.6.1 1.6-2.4 0-2.5-1.2 0-2.4-.1-3.6 0-1.6.1-1.6 2.6 0 2.5z"/><path fill="#231F20" d="M22.9 32.9c-.1 1.7-.2 3.4-.2 5-.1 1.2.2 4-.5 4.9-1.2 1.5-2.2-.5-2.2-1.6 0-.8.1-1.7.1-2.6.1-1.7.2-3.5.3-5.2.1-1.6-2.4-1.6-2.5 0-.2 3.6-2.4 12.8 3.7 12.7 2.4 0 2.9-1.8 3.2-3.9.5-3.1.4-6.3.6-9.4.1-1.5-2.4-1.5-2.5.1z"/><path fill="#231F20" d="M45.7 21.8c3.1.8 2.5 6.9 2.3 9.3-.1 1.6 2.4 1.6 2.5 0 .3-3.7.5-10.4-4.1-11.7-1.6-.5-2.3 1.9-.7 2.4z"/><g><path fill="#231F20" d="M37.9 27.1c-.4 4.4-.8 9.2-.1 13.6.2 1.4.3 3 1.5 4 2.9 2.4 5.4-.7 5.9-3.4.6-2.9.4-6 .6-8.9.2-3.7.8-7.8.4-11.6-.6-5.9-5.2-8.2-10.3-9.9-1.5-.5-2.2 1.9-.7 2.4 5.5 1.8 8.6 4.2 8.6 10.3 0 3.6-.4 7.1-.6 10.7-.1 1.3.3 3.4-.2 4.6.1 1.3-.8 1.9-2.7 1.8 0-.6-.1-1.3-.1-1.9-.9-3.3 0-8.2.3-11.6.1-1.7-2.5-1.7-2.6-.1z"/><path fill="#231F20" d="M36.5 11.7c-.3-1.4-.2-3.5-1.4-4.6-1-.9-3-1.4-4.3-1.6-3.6-.4-5.2 2.2-5.9 5.4-.4 1.6 2.1 2.2 2.4.7.5-2.1 1.2-4 3.8-3.5.8.2 2 .5 2.4 1.2.4.7.4 2.2.6 3 .3 1.7 2.7 1 2.4-.6z"/><path fill="#231F20" d="M25.4 10.4c-5.4 2.8-8.7 7.9-9.5 13.9.8-.1 1.6-.2 2.5-.3-1-2.8-.3-6.2-2.3-8.6-1.6-1.9-4-2.4-6.3-2-1.6.3-.9 2.7.7 2.4 5.4-1 4.4 5.6 5.6 8.8.5 1.4 2.3 1.1 2.5-.3.7-5.1 3.7-9.3 8.2-11.7 1.3-.8 0-3-1.4-2.2z"/><path fill="#231F20" d="M8.5 14.5c.1 1.3 0 2.6-.2 3.8-.1.7.2 1.3.9 1.5.6.2 1.4-.2 1.5-.9.2-1.5.3-3 .3-4.5-.1-1.6-2.6-1.6-2.5.1z"/><path fill="#231F20" d="M9.4 17.4c-2.3 0-8.7 0-8 3.8.2 1.2 1 3.5 2.3 3.8.7.2 1.6-.1 2.3-.2 1.1-.2 2.1-.4 3.2-.6 1.6-.3.9-2.7-.7-2.4-1 .2-2 .3-3 .5-.3 0-.8.2-1 .1-.1 0-.5-1.1-.5-1.3 0-.6.3-.5.9-.7l1.5-.3c1-.1 2.1-.2 3.1-.2 1.5 0 1.5-2.5-.1-2.5z"/><path fill="#231F20" d="M8 22.8c-1 3.3-2.7 8.7 1.2 11.1 1.7 1.1 5.2.5 7.1.4 3.9-.2 7.9-.5 11.8-.7 1.6-.1 1.6-2.6 0-2.5-4.2.2-8.3.5-12.5.7-2.4.1-5.2.4-6.1-2.3-.7-1.9.3-4.2.9-6.1.4-1.5-2-2.1-2.4-.6z"/><path fill="#231F20" d="M12.8 21.4c1.6 0 1.6-2.5 0-2.5s-1.7 2.5 0 2.5z"/><path fill="#231F20" d="M27.8 27.2c-.2 4.9-.8 10-.4 14.9.2 2.3 1.4 4.5 4.1 4.4 7.5-.5 4.2-14.3 4.6-18.7.1-1.6-2.4-1.6-2.5 0-.2 2.4 0 4.8.1 7.3.1 1.1.2 2.2.1 3.3 0 .8-.1 1.5-.2 2.3 0 1.7-1.2 2.2-3.6 1.5-.7-.9.1-5.4.2-6.6.1-2.8.2-5.6.3-8.3-.1-1.7-2.6-1.7-2.7-.1z"/><path fill="#231F20" d="M35.1 33.6h3.6c1.6.1 1.6-2.4 0-2.5-1.2 0-2.4-.1-3.6 0-1.6.1-1.6 2.6 0 2.5z"/><path fill="#231F20" d="M22.9 32.9c-.1 1.7-.2 3.4-.2 5-.1 1.2.2 4-.5 4.9-1.2 1.5-2.2-.5-2.2-1.6 0-.8.1-1.7.1-2.6.1-1.7.2-3.5.3-5.2.1-1.6-2.4-1.6-2.5 0-.2 3.6-2.4 12.8 3.7 12.7 2.4 0 2.9-1.8 3.2-3.9.5-3.1.4-6.3.6-9.4.1-1.5-2.4-1.5-2.5.1z"/><path fill="#231F20" d="M45.7 21.8c3.1.8 2.5 6.9 2.3 9.3-.1 1.6 2.4 1.6 2.5 0 .3-3.7.5-10.4-4.1-11.7-1.6-.5-2.3 1.9-.7 2.4z"/></g><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description about="https://iconscout.com/legal#licenses" dc:title="camel,animal,pet,desert" dc:description="camel,animal,pet,desert" dc:publisher="Iconscout" dc:date="2017-11-11" dc:format="image/svg+xml" dc:language="en"><dc:creator><rdf:Bag><rdf:li>Dinosoft Labs</rdf:li></rdf:Bag></dc:creator></rdf:Description></rdf:RDF></metadata></svg>
\ No newline at end of file
diff --git a/public/images/pieces/new/camel-animal-wildlife-34b2662eb81cfec3.svg b/public/images/pieces/new/camel-animal-wildlife-34b2662eb81cfec3.svg
new file mode 100644 (file)
index 0000000..a67f271
--- /dev/null
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60px" height="60px" viewBox="0 0 60 60" version="1.1">
+    
+    <title>20 -Camel- (Solid)</title>
+    <desc>Created with Sketch.</desc>
+    <defs/>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Icons" transform="translate(-1200.000000, -491.000000)" fill="#000000">
+            <g id="20--Camel--(Solid)" transform="translate(1200.000000, 491.000000)">
+                <path d="M38,16.0061 C37.447,16.0061 37,15.5581 37,15.0061 C37,14.4541 37.447,14.0061 38,14.0061 C38.553,14.0061 39,14.4541 39,15.0061 C39,15.5581 38.553,16.0061 38,16.0061 M38,12.0061 C36.346,12.0061 35,13.3521 35,15.0061 C35,16.6601 36.346,18.0061 38,18.0061 C39.654,18.0061 41,16.6601 41,15.0061 C41,13.3521 39.654,12.0061 38,12.0061" id="Fill-129"/>
+                <path d="M38,20.0061 C35.243,20.0061 33,17.7631 33,15.0061 C33,12.2491 35.243,10.0061 38,10.0061 C40.757,10.0061 43,12.2491 43,15.0061 C43,17.7631 40.757,20.0061 38,20.0061 L38,20.0061 Z M36,25.0061 C34.897,25.0061 34,25.9031 34,27.0061 C34,27.5581 33.553,28.0061 33,28.0061 C32.447,28.0061 32,27.5581 32,27.0061 C32,24.8001 33.794,23.0061 36,23.0061 C36.553,23.0061 37,23.4541 37,24.0061 C37,24.5581 36.553,25.0061 36,25.0061 L36,25.0061 Z M32,56.0061 C32,57.1091 31.103,58.0061 30,58.0061 C28.897,58.0061 28,57.1091 28,56.0061 L28,54.6041 L28,51.7081 C28.017,51.7131 28.033,51.7141 28.05,51.7191 C28.333,51.8001 28.614,51.8601 28.894,51.9051 C28.965,51.9181 29.037,51.9291 29.108,51.9381 C29.408,51.9781 29.706,52.0061 30,52.0061 C30.306,52.0061 30.613,51.9771 30.921,51.9361 C30.97,51.9291 31.018,51.9221 31.066,51.9141 C31.376,51.8651 31.687,51.8021 32,51.7111 L32,54.6131 L32,56.0061 Z M23,24.0061 C23,23.4541 23.447,23.0061 24,23.0061 C26.206,23.0061 28,24.8001 28,27.0061 C28,27.5581 27.553,28.0061 27,28.0061 C26.447,28.0061 26,27.5581 26,27.0061 C26,25.9031 25.103,25.0061 24,25.0061 C23.447,25.0061 23,24.5581 23,24.0061 L23,24.0061 Z M22,20.0061 C19.243,20.0061 17,17.7631 17,15.0061 C17,12.2491 19.243,10.0061 22,10.0061 C24.757,10.0061 27,12.2491 27,15.0061 C27,17.7631 24.757,20.0061 22,20.0061 L22,20.0061 Z M29.999,38.5921 L33.287,35.2991 C33.678,34.9081 34.312,34.9091 34.702,35.2981 C35.093,35.6891 35.093,36.3221 34.703,36.7131 L31,40.4201 L31,43.0061 C31,43.5581 30.553,44.0061 30,44.0061 C29.447,44.0061 29,43.5581 29,43.0061 L29,40.4211 L25.288,36.7141 C24.897,36.3231 24.897,35.6901 25.287,35.2991 C25.678,34.9081 26.312,34.9091 26.702,35.2981 L29.999,38.5921 Z M58.636,4.5621 C53.68,1.5801 47.801,3.3941 43.512,5.6321 C42.699,4.7581 41.794,3.9761 40.812,3.2991 C34.44,-1.0889 25.544,-1.0889 19.177,3.3001 C18.195,3.9771 17.293,4.7571 16.484,5.6251 C12.196,3.3901 6.318,1.5821 1.363,4.5641 C0.491,5.0891 -0.03,6.0371 0.002,7.0391 C0.069,9.1801 0.777,14.2411 5.869,14.9951 C5.906,15.0011 5.943,15.0041 5.981,15.0061 C6.133,15.0101 9.249,15.1111 12.214,14.6801 C12.042,15.7601 11.951,16.8841 11.941,18.0371 C11.91,21.8621 12.823,25.7201 14.654,29.5041 C16.048,32.3851 17.028,34.8171 17.553,36.6461 C19.143,34.4361 21,31.0061 21,27.0061 C21,26.4541 21.447,26.0061 22,26.0061 C22.553,26.0061 23,26.4541 23,27.0061 C23,32.6691 19.851,37.1741 17.994,39.3411 L17.995,41.0501 C18.117,43.8121 19.075,52.7501 26,55.3031 L26,56.0061 C26,58.2121 27.794,60.0061 30,60.0061 C32.206,60.0061 34,58.2121 34,56.0061 L34,55.3171 C41.035,52.7831 41.903,43.8101 41.994,41.0061 L41.994,39.8601 C39.857,36.9011 36.995,32.0091 36.995,27.0061 C36.995,26.4541 37.442,26.0061 37.995,26.0061 C38.548,26.0061 38.995,26.4541 38.995,27.0061 C38.995,30.5441 40.693,34.1361 42.385,36.8391 C42.894,34.9851 43.892,32.4861 45.336,29.5041 C47.167,25.7211 48.079,21.8621 48.048,18.0351 C48.038,16.8811 47.947,15.7571 47.775,14.6761 C50.748,15.1111 53.876,15.0091 54.028,15.0061 C54.066,15.0041 54.104,15.0011 54.141,14.9951 C59.225,14.2421 59.932,9.1791 59.999,7.0381 C60.031,6.0361 59.509,5.0881 58.636,4.5621 L58.636,4.5621 Z" id="Fill-131"/>
+                <path d="M22,16.0061 C21.447,16.0061 21,15.5581 21,15.0061 C21,14.4541 21.447,14.0061 22,14.0061 C22.553,14.0061 23,14.4541 23,15.0061 C23,15.5581 22.553,16.0061 22,16.0061 M22,12.0061 C20.346,12.0061 19,13.3521 19,15.0061 C19,16.6601 20.346,18.0061 22,18.0061 C23.654,18.0061 25,16.6601 25,15.0061 C25,13.3521 23.654,12.0061 22,12.0061" id="Fill-134"/>
+            </g>
+        </g>
+    </g>
+
+       <metadata>
+               <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/">
+                       <rdf:Description about="https://iconscout.com/legal#licenses" dc:title="camel,animal,wildlife" dc:description="camel,animal,wildlife" dc:publisher="Iconscout" dc:date="2017-07-28" dc:format="image/svg+xml" dc:language="en">
+                               <dc:creator>
+                                       <rdf:Bag>
+                                               <rdf:li>Smashicons .</rdf:li>
+                                       </rdf:Bag>
+                               </dc:creator>
+                       </rdf:Description>
+               </rdf:RDF>
+    </metadata></svg>
diff --git a/public/images/pieces/new/camel-animal-wildlife-3b15afb5e788b9ec.svg b/public/images/pieces/new/camel-animal-wildlife-3b15afb5e788b9ec.svg
new file mode 100644 (file)
index 0000000..bc2b030
--- /dev/null
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="60px" height="60px" viewBox="0 0 60 60" version="1.1">
+    
+    <title>20 -Camel- (Outline)</title>
+    <desc>Created with Sketch.</desc>
+    <defs/>
+    <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+        <g id="Icons" transform="translate(-1195.000000, -491.000000)" fill="#000000">
+            <g id="20--Camel--(Outline)" transform="translate(1195.000000, 491.000000)">
+                <path d="M23,15.0061 C23,15.5581 22.553,16.0061 22,16.0061 C21.447,16.0061 21,15.5581 21,15.0061 C21,14.4541 21.447,14.0061 22,14.0061 C22.553,14.0061 23,14.4541 23,15.0061" id="Fill-439"/>
+                <path d="M18.6885,38.0061 C18.3845,38.0061 18.0855,37.8691 17.8895,37.6091 C17.5585,37.1701 17.6435,36.5481 18.0775,36.2141 C18.1465,36.1571 21.0005,33.7781 21.0005,27.0061 C21.0005,26.4541 21.4475,26.0061 22.0005,26.0061 C22.5525,26.0061 23.0005,26.4541 23.0005,27.0061 C23.0005,34.9131 19.4415,37.6901 19.2905,37.8041 C19.1095,37.9401 18.8985,38.0061 18.6885,38.0061" id="Fill-441"/>
+                <path d="M41.3008,38.0061 C41.0908,38.0061 40.8788,37.9401 40.6978,37.8041 C40.5478,37.6891 36.9948,34.9131 36.9948,27.0061 C36.9948,26.4541 37.4428,26.0061 37.9948,26.0061 C38.5478,26.0061 38.9948,26.4541 38.9948,27.0061 C38.9948,33.8181 41.8758,36.1861 41.9048,36.2081 C42.3458,36.5411 42.4328,37.1691 42.0998,37.6091 C41.9028,37.8691 41.6038,38.0061 41.3008,38.0061" id="Fill-443"/>
+                <path d="M30,41.0061 C29.735,41.0061 29.48,40.9011 29.293,40.7141 L25.288,36.7141 C24.897,36.3231 24.897,35.6901 25.287,35.2991 C25.678,34.9081 26.312,34.9091 26.702,35.2981 L29.999,38.5921 L33.287,35.2991 C33.678,34.9081 34.312,34.9091 34.702,35.2981 C35.093,35.6891 35.093,36.3221 34.703,36.7131 L30.708,40.7131 C30.521,40.9011 30.266,41.0061 30.001,41.0061 L30,41.0061 Z" id="Fill-445"/>
+                <path d="M30,44.0061 C29.447,44.0061 29,43.5581 29,43.0061 L29,40.0061 C29,39.4541 29.447,39.0061 30,39.0061 C30.553,39.0061 31,39.4541 31,40.0061 L31,43.0061 C31,43.5581 30.553,44.0061 30,44.0061" id="Fill-447"/>
+                <path d="M22,12.0061 C20.346,12.0061 19,13.3521 19,15.0061 C19,16.6601 20.346,18.0061 22,18.0061 C23.654,18.0061 25,16.6601 25,15.0061 C25,13.3521 23.654,12.0061 22,12.0061 M22,20.0061 C19.243,20.0061 17,17.7631 17,15.0061 C17,12.2491 19.243,10.0061 22,10.0061 C24.757,10.0061 27,12.2491 27,15.0061 C27,17.7631 24.757,20.0061 22,20.0061" id="Fill-449"/>
+                <path d="M39,15.0061 C39,15.5581 38.553,16.0061 38,16.0061 C37.447,16.0061 37,15.5581 37,15.0061 C37,14.4541 37.447,14.0061 38,14.0061 C38.553,14.0061 39,14.4541 39,15.0061" id="Fill-451"/>
+                <path d="M38,12.0061 C36.346,12.0061 35,13.3521 35,15.0061 C35,16.6601 36.346,18.0061 38,18.0061 C39.654,18.0061 41,16.6601 41,15.0061 C41,13.3521 39.654,12.0061 38,12.0061 M38,20.0061 C35.243,20.0061 33,17.7631 33,15.0061 C33,12.2491 35.243,10.0061 38,10.0061 C40.757,10.0061 43,12.2491 43,15.0061 C43,17.7631 40.757,20.0061 38,20.0061" id="Fill-453"/>
+                <path d="M30,52.0061 C28.215,52.0061 26.328,51.2651 24.392,49.8041 C23.951,49.4721 23.863,48.8441 24.196,48.4031 C24.528,47.9641 25.154,47.8741 25.597,48.2081 C27.178,49.4011 28.659,50.0061 30,50.0061 C31.35,50.0061 32.788,49.4181 34.399,48.2071 C34.841,47.8751 35.467,47.9641 35.8,48.4051 C36.131,48.8471 36.042,49.4741 35.601,49.8051 C33.631,51.2861 31.799,52.0061 30,52.0061" id="Fill-455"/>
+                <path d="M28,51.7082 L28,56.0062 C28,57.1092 28.897,58.0062 30,58.0062 C31.103,58.0062 32,57.1092 32,56.0062 L32,51.7072 C30.641,52.1042 29.359,52.1042 28,51.7082 M30,60.0062 C27.794,60.0062 26,58.2112 26,56.0062 L26,50.2502 C26,49.9062 26.177,49.5862 26.469,49.4032 C26.761,49.2212 27.124,49.2022 27.436,49.3502 C29.232,50.2192 30.761,50.2232 32.563,49.3472 C32.875,49.1972 33.239,49.2172 33.531,49.3992 C33.822,49.5832 34,49.9032 34,50.2472 L34,56.0062 C34,58.2112 32.206,60.0062 30,60.0062" id="Fill-457"/>
+                <path d="M32.999,55.6135 C32.562,55.6135 32.159,55.3225 32.036,54.8805 C31.889,54.3485 32.2,53.7975 32.732,53.6495 C39.146,51.8695 39.913,43.4975 39.995,40.9735 L39.994,39.0065 C40.036,36.3875 41.943,31.9215 43.535,28.6335 C45.231,25.1285 46.076,21.5685 46.048,18.0515 C46.035,16.5115 45.864,15.0335 45.539,13.6595 C45.459,13.3245 45.559,12.9715 45.801,12.7265 C46.043,12.4815 46.394,12.3775 46.731,12.4535 C49.594,13.0975 53.395,13.0205 53.903,13.0085 C57.317,12.4665 57.936,8.9995 58.001,6.9745 C58.01,6.6965 57.857,6.4285 57.604,6.2765 C53.188,3.6175 47.645,5.6175 43.772,7.7625 C43.355,7.9935 42.83,7.8975 42.522,7.5315 C41.693,6.5455 40.736,5.6755 39.678,4.9465 C33.973,1.0185 26.011,1.0175 20.311,4.9465 C19.253,5.6765 18.298,6.5445 17.475,7.5245 C17.167,7.8905 16.642,7.9875 16.225,7.7565 C13.057,6.0025 7.046,3.4785 2.395,6.2785 C2.143,6.4295 1.991,6.6965 2,6.9755 C2.064,9.0005 2.685,12.4645 6.106,13.0085 C6.61,13.0195 10.403,13.0955 13.26,12.4585 C13.596,12.3825 13.947,12.4875 14.189,12.7325 C14.432,12.9775 14.53,13.3305 14.45,13.6655 C14.125,15.0385 13.954,16.5145 13.941,18.0535 C13.913,21.5685 14.758,25.1285 16.455,28.6335 C18.047,31.9235 19.953,36.3905 19.994,38.9905 L19.994,41.0065 C20.104,43.4815 20.958,51.8435 27.274,53.6425 C27.805,53.7935 28.113,54.3465 27.962,54.8785 C27.812,55.4095 27.259,55.7175 26.726,55.5665 C19.123,53.4005 18.121,43.9075 17.995,41.0505 L17.994,39.0065 C17.967,37.2785 16.78,33.8985 14.654,29.5045 C12.823,25.7205 11.91,21.8625 11.941,18.0375 C11.951,16.8845 12.042,15.7605 12.214,14.6795 C9.249,15.1115 6.133,15.0105 5.981,15.0055 C5.943,15.0045 5.906,15.0005 5.869,14.9955 C0.777,14.2405 0.069,9.1795 0.002,7.0395 C-0.03,6.0375 0.491,5.0885 1.363,4.5645 C6.318,1.5825 12.196,3.3895 16.484,5.6255 C17.293,4.7575 18.195,3.9765 19.177,3.3005 C25.544,-1.0885 34.44,-1.0895 40.811,3.2995 C41.794,3.9755 42.699,4.7585 43.512,5.6325 C47.801,3.3935 53.68,1.5795 58.636,4.5625 C59.509,5.0875 60.031,6.0355 59.999,7.0375 C59.932,9.1795 59.225,14.2415 54.141,14.9955 C54.103,15.0005 54.066,15.0045 54.028,15.0055 C53.876,15.0095 50.748,15.1115 47.775,14.6755 C47.947,15.7575 48.038,16.8815 48.048,18.0345 C48.079,21.8625 47.167,25.7205 45.336,29.5045 C43.209,33.8965 42.022,37.2775 41.994,39.0225 L41.994,41.0065 C41.9,43.9065 40.995,53.4325 33.268,55.5765 C33.178,55.6015 33.088,55.6135 32.999,55.6135" id="Fill-459"/>
+                <path d="M33,28.0061 C32.447,28.0061 32,27.5581 32,27.0061 C32,24.8001 33.794,23.0061 36,23.0061 C36.553,23.0061 37,23.4541 37,24.0061 C37,24.5581 36.553,25.0061 36,25.0061 C34.897,25.0061 34,25.9031 34,27.0061 C34,27.5581 33.553,28.0061 33,28.0061" id="Fill-496"/>
+                <path d="M27,28.0061 C26.447,28.0061 26,27.5581 26,27.0061 C26,25.9031 25.103,25.0061 24,25.0061 C23.447,25.0061 23,24.5581 23,24.0061 C23,23.4541 23.447,23.0061 24,23.0061 C26.206,23.0061 28,24.8001 28,27.0061 C28,27.5581 27.553,28.0061 27,28.0061" id="Fill-498"/>
+            </g>
+        </g>
+    </g>
+
+       <metadata>
+               <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/">
+                       <rdf:Description about="https://iconscout.com/legal#licenses" dc:title="camel,animal,wildlife" dc:description="camel,animal,wildlife" dc:publisher="Iconscout" dc:date="2017-07-24" dc:format="image/svg+xml" dc:language="en">
+                               <dc:creator>
+                                       <rdf:Bag>
+                                               <rdf:li>Smashicons .</rdf:li>
+                                       </rdf:Bag>
+                               </dc:creator>
+                       </rdf:Description>
+               </rdf:RDF>
+    </metadata></svg>
diff --git a/public/images/pieces/new/unicorn-myth-legend-halloween-fantasy-37ec614cb63bc127.svg b/public/images/pieces/new/unicorn-myth-legend-halloween-fantasy-37ec614cb63bc127.svg
new file mode 100644 (file)
index 0000000..c9e930b
--- /dev/null
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" width="512px" height="512px" viewBox="0 0 512 512" enable-background="new 0 0 512 512" xml:space="preserve">
+<g id="unicorn">
+       <path d="M321.323,127.995c-5.906,0-10.672,4.773-10.672,10.664s4.766,10.672,10.672,10.672c5.891,0,10.656-4.781,10.656-10.672   S327.214,127.995,321.323,127.995z"/>
+       <path d="M458.385,214.017c-0.891-5.664-4.5-14.843-24.734-35.726c-11.078-11.445-26.172-25.422-44.844-41.531   c-8.358-7.211-16.718-14.226-24.499-20.656l61.968-99.656c0.016-0.023,0.031-0.039,0.047-0.062l0.047-0.094   c0.047-0.062,0.078-0.141,0.125-0.203c0.125-0.227,0.266-0.453,0.375-0.68c0.062-0.125,0.109-0.25,0.172-0.375   c0.078-0.188,0.156-0.375,0.234-0.57c0.062-0.172,0.125-0.336,0.172-0.508c0.047-0.156,0.109-0.305,0.156-0.461   c0.047-0.195,0.094-0.398,0.125-0.594c0.031-0.133,0.062-0.266,0.094-0.406c0.031-0.203,0.062-0.406,0.078-0.617   c0.016-0.133,0.031-0.266,0.047-0.406c0.016-0.195,0.016-0.391,0.031-0.586c0-0.148,0-0.305,0-0.453   c0-0.18-0.016-0.352-0.031-0.523s-0.031-0.352-0.047-0.523c-0.016-0.148-0.047-0.297-0.062-0.445   c-0.031-0.195-0.078-0.391-0.109-0.586c-0.031-0.133-0.062-0.258-0.109-0.391c-0.047-0.203-0.094-0.406-0.172-0.609   c-0.031-0.125-0.078-0.25-0.125-0.383c-0.078-0.188-0.156-0.383-0.234-0.57c-0.062-0.148-0.141-0.289-0.203-0.43   c-0.078-0.164-0.156-0.32-0.25-0.484c-0.094-0.18-0.203-0.352-0.312-0.531c-0.078-0.117-0.141-0.227-0.219-0.336   c-0.156-0.219-0.312-0.43-0.484-0.633c-0.047-0.062-0.078-0.125-0.125-0.18c-0.016-0.016-0.031-0.023-0.031-0.031   c-0.172-0.203-0.359-0.391-0.547-0.578c-0.062-0.07-0.125-0.148-0.203-0.219c-0.141-0.133-0.281-0.25-0.422-0.375   c-0.141-0.117-0.266-0.242-0.406-0.352c-0.094-0.062-0.188-0.125-0.266-0.188c-0.203-0.148-0.422-0.305-0.641-0.438   c0-0.008-0.016-0.016-0.031-0.023c-0.062-0.047-0.141-0.078-0.203-0.117c-0.234-0.133-0.453-0.258-0.688-0.375   c-0.125-0.062-0.25-0.109-0.359-0.172c-0.203-0.086-0.391-0.172-0.578-0.242c-0.172-0.062-0.344-0.117-0.516-0.172   c-0.141-0.047-0.297-0.102-0.453-0.141c-0.203-0.055-0.391-0.102-0.594-0.141c-0.141-0.031-0.266-0.062-0.406-0.086   c-0.203-0.039-0.406-0.062-0.609-0.086c-0.141-0.016-0.281-0.031-0.406-0.039c-0.203-0.016-0.391-0.023-0.594-0.023   c-0.156-0.008-0.297-0.016-0.453-0.008c-0.172,0-0.344,0.016-0.516,0.031c-0.188,0.008-0.359,0.023-0.531,0.039   c-0.156,0.023-0.297,0.047-0.453,0.07c-0.188,0.031-0.391,0.062-0.578,0.109c-0.125,0.031-0.266,0.062-0.391,0.102   c-0.203,0.047-0.406,0.102-0.609,0.172c-0.125,0.039-0.25,0.086-0.375,0.133c-0.203,0.07-0.391,0.141-0.578,0.227   c-0.141,0.062-0.281,0.133-0.438,0.203c-0.156,0.086-0.312,0.156-0.469,0.25c-0.188,0.094-0.359,0.211-0.531,0.32   c-0.125,0.07-0.234,0.141-0.344,0.219c-0.219,0.148-0.422,0.305-0.625,0.469c-0.062,0.055-0.125,0.094-0.188,0.141l-0.078,0.07   c-0.031,0.016-0.047,0.031-0.062,0.047l-84.218,70.648c-4.594-19.469-12.266-35.367-22.938-47.421   c-10.984-12.398-21.297-16.055-22.438-16.43c-2.906-0.953-6.094-0.617-8.734,0.93s-4.484,4.156-5.078,7.164l-9.922,50.953   c-5.188,0.609-12.297,1.867-20.625,4.406c-8.016,0.242-38.828,2.75-74.078,26.367c-23.188,15.539-43.656,37.093-60.843,64.078   c-21.156,33.219-37.359,74.828-48.203,123.688c-0.703,3.203,0.094,6.547,2.172,9.078s5.188,3.968,8.484,3.905   c4.953-0.125,20.016,0.422,30.094,4.219c0.141,0.047,0.297,0.094,0.438,0.141c0.078,0.031,0.172,0.062,0.25,0.094   c0.344,0.094,34.109,10.516,74.093,40.375c23.375,17.469,44.312,38.109,62.203,61.327c22.344,29.016,40.016,62.219,52.5,98.672   c1.297,3.766,4.578,6.5,8.516,7.094c0.531,0.078,1.062,0.109,1.578,0.109c3.391,0,6.609-1.609,8.641-4.406   c1.656-2.281,40.438-56.406,40.438-112.922c0-49.062-31.906-101.326-41.422-115.811l6.734-34.594   c15.312,4.102,30.219,4.812,39.578,4.734c0.812,3.586,1.906,7.875,3.297,12.258c5.516,17.539,12.797,27.398,22.266,30.133   c2.656,0.766,5.344,1.109,8.031,1.109c15.171,0,29.937-10.625,33.187-13.109c8.25,6.016,14.344,3.719,17.281,1.766   c4.984-3.328,12.547-13.367,17.969-23.891C455.01,246.697,460.963,230.611,458.385,214.017z M335.761,93.002l37.203-31.211   l-25.328,40.719C343.12,98.87,339.104,95.651,335.761,93.002z M118.824,175.744c13.187-20.922,28.421-38.203,45.39-51.546   c-31.531,43.476-63.046,128.327-73.234,157.023c-4.875-1.031-9.734-1.656-13.984-2.031   C87.058,238.611,101.105,203.861,118.824,175.744z M423.494,259.018c-3.109-3.227-7.188-8.141-10.547-12.813   c-2.953-4.102-8.359-5.578-12.984-3.531c-4.609,2.039-7.172,7.039-6.109,11.984l2.391,11.204   c-5.688,3.344-12.765,6.188-17.015,5.094c-1.188-0.781-4.75-5.172-8.406-17.282c-2.703-8.922-4.031-17.281-4.047-17.352   c-0.859-5.578-5.922-9.516-11.547-8.984c-0.156,0.016-15.703,1.445-33.547-1.852c-22.391-4.133-37.234-13.382-44.109-27.5   c-2.578-5.297-8.969-7.492-14.266-4.914c-5.297,2.586-7.5,8.969-4.922,14.266c6.688,13.703,17.391,22.968,29.344,29.195   l-8.281,42.579c-0.547,2.844,0.078,5.797,1.75,8.172c0.391,0.578,40.125,57.765,40.125,107.389c0,31.562-14.656,63.5-25.359,82.625   c-12.562-30.859-28.828-59.266-48.485-84.703c-19.188-24.812-41.64-46.843-66.734-65.468   c-29.516-21.922-55.578-33.89-69.421-39.374c4.609-12.922,13.484-37.047,24.5-63.141c21.141-50.085,40.375-84.625,55.641-99.882   c23.984-23.984,49.078-31.773,63.046-34.305l-0.984,16.945c-0.344,5.883,4.141,10.93,10.016,11.273   c0.219,0.016,0.422,0.016,0.641,0.016c5.609,0,10.297-4.367,10.641-10.039l1.688-28.742l8.266-42.468   c1.109,1.109,2.281,2.367,3.453,3.781c7.156,8.546,16.438,24.757,20.031,53.398c0,0.102,0.031,0.203,0.047,0.305   c0.031,0.219,0.062,0.438,0.109,0.648c0.031,0.125,0.062,0.242,0.094,0.367c0.062,0.219,0.109,0.438,0.188,0.648   c0.031,0.117,0.078,0.234,0.125,0.344c0.078,0.211,0.156,0.422,0.25,0.633c0.047,0.125,0.109,0.242,0.172,0.359   c0.078,0.188,0.172,0.383,0.281,0.57c0.078,0.141,0.172,0.266,0.25,0.406c0.094,0.156,0.188,0.32,0.297,0.477   s0.234,0.305,0.359,0.461c0.078,0.102,0.141,0.211,0.234,0.312c0.016,0.023,0.031,0.039,0.062,0.062   c0.203,0.25,0.438,0.492,0.672,0.719c0.062,0.062,0.109,0.117,0.172,0.172c0.234,0.219,0.484,0.43,0.734,0.633   c0.016,0,0.031,0.023,0.078,0.055c0.016,0.008,0.031,0.023,0.047,0.031c2.078,1.617,31.844,24.766,61.875,50.64   c58.655,50.539,62.733,63.585,62.999,64.875C439.682,232.587,429.885,250.439,423.494,259.018z"/>
+</g>
+
+       
+       <metadata>
+               <rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/">
+                       <rdf:Description about="https://iconscout.com/legal#licenses" dc:title="Unicorn, Myth, Legend, Halloween, Fantasy" dc:description="Unicorn, Myth, Legend, Halloween, Fantasy" dc:publisher="Iconscout" dc:date="2016-12-14" dc:format="image/svg+xml" dc:language="en">
+                               <dc:creator>
+                                       <rdf:Bag>
+                                               <rdf:li>Nikita Golubev</rdf:li>
+                                       </rdf:Bag>
+                               </dc:creator>
+                       </rdf:Description>
+               </rdf:RDF>
+    </metadata></svg>
diff --git a/public/images/pieces/new/wildebeest-animal-wild-wildlife-face-326845431b848a31.svg b/public/images/pieces/new/wildebeest-animal-wild-wildlife-face-326845431b848a31.svg
new file mode 100644 (file)
index 0000000..21a3c9a
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 62 64" xml:space="preserve"><g id="wildebeest__x5F_glyphs"><path d="M25 49c-.6 0-1 .4-1 1s.4 1 1 1h3c.6 0 1-.4 1-1s-.4-1-1-1h-3z"/><path d="M34 49c-.6 0-1 .4-1 1s.4 1 1 1h3c.6 0 1-.4 1-1s-.4-1-1-1h-3z"/><path d="M11 36V24.7c-.1.2-.2.3-.4.5-1.3 1.4-3.1 2.3-5 2.4H5v14.9C5 43.8 3.9 45 2.5 45S0 43.4 0 42v2.5c0 3.6 3 6.9 9 6.5 6.9-.5 7-4.4 7-6.4-3.1-1.4-5-5.6-5-8.6z"/><path d="M11 12c0-3.9 3.1-7 7-7h10.8c-2.2-3-5.9-5-11.3-5C10.6 0 5 5.6 5 12.5V19h6v-7z"/><path d="M5.5 25.6c1.4-.1 2.7-.7 3.6-1.7.7-.9 1.2-1.9 1.3-2.9H.2c.3 1.1.8 2.1 1.6 3 1.1 1.1 2.4 1.6 3.7 1.6z"/><path d="M51 12v7h6v-6.5C57 5.6 51.4 0 44.5 0c-5.4 0-9 2-11.3 5H44c3.9 0 7 3.1 7 7z"/><path d="M61.8 43c-.5 1.6-2.3 2.9-4 1.2-.5-.6-.8-1.4-.8-2.2V27.6h-.6c-1.9-.1-3.7-1-5-2.4-.1-.2-.3-.3-.4-.5V36c0 3-1.9 7.2-5 8.6 0 2 .1 5.9 7 6.4 6 .4 9-2.9 9-6.5V43h-.2z"/><path d="M52.9 23.8c.9 1 2.2 1.7 3.6 1.7 1.3.1 2.6-.5 3.7-1.6.8-.8 1.4-1.9 1.6-3H51.6c.1 1.1.6 2.1 1.3 2.9z"/><path d="M49 36V21h-6c-2.2 0-4 1.8-4 4v27.6L37.4 57h-13L23 53.6V25c0-2.2-1.8-4-4-4h-6v15c0 2.2 1.5 5.4 3.5 6.6l6.4 16.1c.1 3 2.7 5.3 6.1 5.3h4c3.3 0 5.8-2.2 5.9-5.3l5.9-15.8c2.3-.7 4.2-4.4 4.2-6.9zm-31-7c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2zm15 33h-4c-1.9 0-3.8-1-4.1-3h11.9c-.2 1.8-1.7 3-3.8 3zm11-33c-1.1 0-2-.9-2-2s.9-2 2-2 2 .9 2 2-.9 2-2 2z"/><path d="M43 19h6v-7c0-2.8-2.2-5-5-5H18c-2.8 0-5 2.2-5 5v7h6c3.3 0 6 2.7 6 6v20h1c2.1 0 3.9 1.1 5 2.7 1.1-1.6 2.9-2.7 5-2.7h1V25c0-3.3 2.7-6 6-6zm-7-1h-9c-.6 0-1-.4-1-1s.4-1 1-1h9c.6 0 1 .4 1 1s-.4 1-1 1zm0-4h-9c-.6 0-1-.4-1-1s.4-1 1-1h9c.6 0 1 .4 1 1s-.4 1-1 1z"/></g><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description about="https://iconscout.com/legal#licenses" dc:title="wildebeest" dc:description="wildebeest" dc:publisher="Iconscout" dc:date="2017-09-07" dc:format="image/svg+xml" dc:language="en"><dc:creator><rdf:Bag><rdf:li>Madeby Grids</rdf:li></rdf:Bag></dc:creator></rdf:Description></rdf:RDF></metadata></svg>
\ No newline at end of file
diff --git a/public/images/pieces/new/wildebeest-animal-wildlife-31b7b8fe2ffee150.svg b/public/images/pieces/new/wildebeest-animal-wildlife-31b7b8fe2ffee150.svg
new file mode 100644 (file)
index 0000000..54020bf
--- /dev/null
@@ -0,0 +1 @@
+<?xml version="1.0" encoding="UTF-8"?><svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" id="Layer_1" x="0px" y="0px" viewBox="0 0 64 64" xml:space="preserve"><g id="wildebeest__x5F_line"><path d="M63.2 42c-.5-.1-.9.2-1.1.6-.4 1.2-1.2 2.3-1.6 2.3-.8 0-1.5-.7-1.5-1.5V28.1c1-.4 1.9-1 2.7-1.8 1.4-1.4 2.2-3.4 2.3-5.3 0-.3-.1-.5-.3-.7-.2-.2-.4-.3-.7-.3h-4v-6.5C59 6.1 52.9 0 45.5 0c-7.6 0-11.3 3.7-13.1 7h-.8c-1.8-3.3-5.5-7-13.1-7C11.1 0 5 6.1 5 13.5V20H1c-.3 0-.5.1-.7.3-.2.2-.3.5-.3.8.1 1.9 1 3.8 2.3 5.3.8.8 1.7 1.4 2.7 1.7v15.3c0 .9-.7 1.6-1.5 1.6-.3 0-1.1-1.1-1.6-2.3-.2-.5-.6-.7-1.1-.6-.5 0-.8.4-.8.9v2.5c0 2 .8 3.9 2.3 5.2C3.4 51.8 5.5 53 9 53h1.1c7.9-.6 7.9-5.4 7.9-7.5v-.6c.1 0 .2.1.3.1L24 59.2c.1 2.9 2.4 4.8 6 4.8h4c3.6 0 5.9-1.9 6-4.8l5.7-14.3c.1 0 .2-.1.3-.1v.6c0 2.1 0 6.9 7.9 7.5H55c3.4 0 5.5-1.2 6.7-2.3 1.5-1.4 2.3-3.2 2.3-5.2V43c0-.5-.3-.9-.8-1zm-9.1 9c-6.1-.5-6.1-3.5-6.1-5.5V44v-.2c1.9-1.6 3-4.6 3-6.8V25.7c.1.2.2.3.4.5 1.3 1.4 3.1 2.3 5 2.4h.6v14.9c0 1.9 1.6 3.5 3.5 3.5.5 0 1-.2 1.4-.5-.2 1.1-.7 2-1.5 2.8-1.5 1.3-3.6 1.9-6.3 1.7zM35.2 61.9c-.4.1-.7.1-.9.1h-4.6c-.3 0-.6 0-.9-.1-.8-.1-1.7-.5-2.3-1.2-.3-.4-.5-1-.5-1.7h12c0 .7-.2 1.3-.5 1.7-.6.7-1.5 1.1-2.3 1.2zM16 44v1.5c0 2 0 5.1-6.1 5.5-2.7.2-4.9-.4-6.3-1.7-.8-.8-1.3-1.7-1.5-2.8.4.3.9.5 1.4.5C5.4 47 7 45.4 7 43.5V28.6h.6c1.9-.1 3.7-1 5-2.4.1-.2.3-.3.4-.5V37c0 2.2 1.2 5.1 3 6.8v.2zM5 22h7.4c-.1 1-.6 2-1.3 2.8-.9 1-2.2 1.7-3.6 1.7H7c-.3 0-.7-.1-1-.2-.3-.1-.7-.3-1-.5-.4-.3-.8-.6-1.2-1-.8-.8-1.4-1.9-1.6-3H5zm2-8.5C7 7.2 12.2 2 18.5 2c4.9 0 8.5 1.7 10.8 5H19c-3.3 0-6 2.7-6 6v7H7v-6.5zM45.5 2C51.8 2 57 7.2 57 13.5V20h-6v-7c0-3.3-2.7-6-6-6H34.7c2.3-3.3 5.9-5 10.8-5zM59 25.9c-.3.2-.7.3-1 .5-.3.1-.7.2-1 .2h-.5c-1.4-.1-2.7-.7-3.6-1.7-.7-.9-1.2-1.9-1.3-2.9h10.2c-.3 1.1-.8 2.1-1.6 3-.4.3-.8.7-1.2.9zM33.4 9H45c2.2 0 4 1.8 4 4v7h-5c-2.2 0-4.1 1.2-5.2 3-.5.9-.8 1.9-.8 3v20h-1c-2.1 0-3.9 1.1-5 2.7-1.1-1.6-2.9-2.7-5-2.7h-1V26c0-1.1-.3-2.1-.8-3-1-1.8-3-3-5.2-3h-5v-7c0-2.2 1.8-4 4-4H33.4zM29 50h-2.9c-.1-.3-.1-.7-.1-1v-1h1c2.2 0 4 1.8 4 4v1h-1c-1 0-1.9-.4-2.6-1H29c.6 0 1-.4 1-1s-.4-1-1-1zm4 2c0-2.2 1.8-4 4-4h1v1c0 .3-.1.7-.1 1H35c-.6 0-1 .4-1 1s.4 1 1 1h1.6c-.7.6-1.6 1-2.6 1h-1v-1zm-15.4-9.6c-1.4-1-2.6-3.5-2.6-5.4V22h5c2.2 0 4 1.8 4 4v23c0 1.2.4 2.4 1 3.3 1.1 1.6 2.9 2.7 5 2.7h1v2h-5.7l-.3-.7-5.1-12.7c-.1-.4-.5-.6-.9-.6-.5 0-.9-.2-1.4-.6zm26.5 1.2L39 56.3l-.3.7H33v-2h1c2.1 0 3.9-1.1 5-2.7.6-1 1-2.1 1-3.3V26c0-2.2 1.8-4 4-4h5v15c0 1.9-1.2 4.4-2.6 5.4-.5.4-.9.6-1.4.6-.4 0-.8.2-.9.6z"/><circle cx="19" cy="28" r="2"/><circle cx="45" cy="28" r="2"/><path d="M28 13c-.6 0-1 .4-1 1s.4 1 1 1h9c.6 0 1-.4 1-1s-.4-1-1-1h-9z"/><path d="M37 17h-9c-.2 0-.4.1-.6.2-.2.2-.4.5-.4.8v.2c.1.5.5.8 1 .8h9c.1 0 .2 0 .3-.1.4-.1.7-.5.7-.9 0-.6-.4-1-1-1z"/></g><metadata><rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:dc="http://purl.org/dc/elements/1.1/"><rdf:Description about="https://iconscout.com/legal#licenses" dc:title="wildebeest" dc:description="wildebeest" dc:publisher="Iconscout" dc:date="2017-09-06" dc:format="image/svg+xml" dc:language="en"><dc:creator><rdf:Bag><rdf:li>Madeby Grids</rdf:li></rdf:Bag></dc:creator></rdf:Description></rdf:RDF></metadata></svg>
\ No newline at end of file
diff --git a/public/images/pieces/wb.svg b/public/images/pieces/wb.svg
new file mode 100644 (file)
index 0000000..2dfcf08
--- /dev/null
@@ -0,0 +1,11 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1024 1166q97 0 186 15 98-35 142-109 38-64 38-141 0-46-23-101t-75-101q-59-49-129-107t-139-137q-70 78-140 136t-128 108q-53 45-75 100t-23 102q0 77 37 141 43 74 143 109 88-15 186-15z" fill-rule="nonzero" display="block" fill="#fff"/>
+ <path style="color:black;" d="m988 1138l-83 1q-34 0-34 34t34 34h83v86q0 35 36 35 35 0 35-35v-86h86q33 0 33-34t-33-34h-86v-82q0-36-35-36-36 0-36 36v81zm36-578q68 0 132 11t125 28q-117 31-257 31-142 0-257-31 58-16 123-27t134-12zm0 1089q68 0 68 68t-68 68-68-68 68-68zm0-949q117 0 225-23l-48 123q-88 14-177 14-91 0-178-14l-48-123q107 23 226 23zm0 182q97 0 186-15 98 35 142 109 38 64 38 141 0 46-23 101t-75 101q-59 49-129 107t-139 137q-70-78-140-136t-128-108q-53-45-75-100t-23-102q0-77 37-141 43-74 143-109 88 15 186 15zm-36-377h-32q-56-90-107-113-24-12-53-22t-67-10q-7 0-107 16-48 7-76 15t-44 10q-57 7-133-6-46-8-86-29l48-78q12 12 31 15t36 8q42 7 80 2 13-3 51-7t101-15q75-11 102-11 105 0 161 40 34 26 64 72t31 113zm36-113q-14-57-34-79t-53-46q-36-25-85-42t-109-9l-281 39q-17 2-30 0t-26-2q-21 0-53-9t-51-28l-97 159q18 20 32 28t33 17q58 27 124 33 28 2 55 1t56 2q54-9 108-16t110-16q60 0 81 12 11 6 35 22t48 47q-53 6-108 20t-97 31l104 258q-78 45-109 72t-49 64q-26 46-33 89t-7 77q1 60 28 132t104 130q63 48 123 99t119 119q-74 38-74 121 0 56 39 96t97 40q56 0 96-40t40-96q0-82-74-121 58-68 117-119t125-99q75-57 102-129t29-133q0-34-7-77t-32-89q-20-36-50-63t-108-73l104-258q-44-16-99-30t-106-21q23-31 47-47t36-22q21-12 81-12 54 8 108 15t110 17q27-3 54-2t57-1q64-6 124-33 18-9 32-17t33-28l-98-159q-18 18-50 27t-53 10q-13 0-26 2t-31 0l-280-39q-60-9-111 8t-85 45q-33 27-52 46t-33 77zm35 113q0-66 30-112t66-73q55-40 161-40 26 0 102 11 62 10 100 14t51 8q38 5 80-2 16-4 35-7t33-16l48 78q-41 21-87 29-76 13-133 6-17-2-44-10t-75-15q-101-16-107-16-39 0-68 10t-52 22q-53 24-108 113h-32z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1024 1488q68 0 132-11t125-28q-117-31-257-31-142 0-257 31 58 16 123 27t134 12z" display="block"/>
+  <path style="color:black;" d="m1024 399q68 0 68-68t-68-68-68 68 68 68z" display="block"/>
+  <path style="color:black;" d="m1024 1348q117 0 225 23l-48-123q-88-14-177-14-91 0-178 14l-48 123q107-23 226-23z" display="block"/>
+  <path style="color:black;" d="m988 1543h-32q-56 90-107 113-24 12-53 22t-67 10q-7 0-107-16-48-7-76-15t-44-10q-57-7-133 6-46 8-86 29l48 78q12-12 31-15t36-8q42-7 80-2 13 3 51 7t101 15q75 11 102 11 105 0 161-40 34-26 64-72t31-113z" display="block"/>
+  <path style="color:black;" d="m1059 1543q0 66 30 112t66 73q55 40 161 40 26 0 102-11 62-10 100-14t51-8q38-5 80 2 16 4 35 7t33 16l48-78q-41-21-87-29-76-13-133-6-17 2-44 10t-75 15q-101 16-107 16-39 0-68-10t-52-22q-53-24-108-113h-32z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/wk.svg b/public/images/pieces/wk.svg
new file mode 100644 (file)
index 0000000..a31f36b
--- /dev/null
@@ -0,0 +1,11 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m524 583q190 48 504 48 308 0 497-46l25 147q-201 53-526 53-327 0-525-54l25-148zm-61-61l-33 187q-1 0-3 4-5 7-28 18t-55 40q-44 37-68 60t-45 50q-61 84-68 203-10 115 93 229 104 114 281 107 66-4 155-32 29-12 59-23t61-24q16-8 28-16-5 21-5 42 0 78 55 133t134 56q78 0 133-55t55-133q0-16-4-42 14 9 27 15 46 20 121 47 86 29 155 33 177 8 280-107 101-114 94-229-8-119-69-203-20-27-45-50t-67-60q-33-28-56-39t-27-19q-1-2-2-3t-1-2l-32-188 66-247q-50-45-224-74t-402-29q-232 0-408 30t-221 77l66 244zm1081-117l-30 115q-198 44-490 44-291 0-489-44l-32-116q191 56 522 56 329 0 519-55zm26-94q-193 78-542 78-362 0-548-80 176-70 545-70 176 0 321 19t224 53zm-581 542q-1 39-3 77t-15 86q-41 134-124 216-43 42-132 78-102 40-193 40-158 0-234-113-43-60-43-150 0-98 48-161 29-37 74-74t84-67q175 63 538 68zm35 186q7 28 12 39 10 39 23 66 6 17 17 39t25 52q8 17 17 41t18 49q8 20 8 43 0 49-35 83t-85 35q-119 0-119-119 0-23 8-43 22-65 34-90 13-29 24-51t19-40q13-33 22-66 2-6 12-38zm34-186q172-2 315-20t224-47q38 30 83 66t75 75q48 61 48 161 0 90-43 150-77 112-234 112-94 0-193-39-87-35-132-78-84-84-124-216-14-47-16-85t-3-79zm1 706h-71v131h-83q-34 0-34 33v1q0 33 34 33h83v85q0 35 36 35 35 0 35-35v-85h86q33 0 33-33v-1q0-33-33-33l-85-1-1-130z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m524 1465q190-48 504-48 308 0 497 46l25-147q-201-53-526-53-327 0-525 54l25 148z" display="block"/>
+  <path style="color:black;" d="m1544 1643-30-115q-198-44-490-44-291 0-489 44l-32 116q191-56 522-56 329 0 519 55z" display="block"/>
+  <path style="color:black;" d="m1570 1737q-193-78-542-78-362 0-548 80 176 70 545 70 176 0 321-19t224-53z" display="block"/>
+  <path style="color:black;" d="m989 1195q-1-39-3-77t-15-86q-41-134-124-216-43-42-132-78-102-40-193-40-158 0-234 113-43 60-43 150 0 98 48 161 29 37 74 74t84 67q175-63 538-68z" display="block"/>
+  <path style="color:black;" d="m1024 1009q7-28 12-39 10-39 23-66 6-17 17-39t25-52q8-17 17-41t18-49q8-20 8-43 0-49-35-83t-85-35q-119 0-119 119 0 23 8 43 22 65 34 90 13 29 24 51t19 40q13 33 22 66 2 6 12 38z" display="block"/>
+  <path style="color:black;" d="m1058 1195q172 2 315 20t224 47q38-30 83-66t75-75q48-61 48-161 0-90-43-150-77-112-234-112-94 0-193 39-87 35-132 78-84 84-124 216-14 47-16 85t-3 79z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/wn.svg b/public/images/pieces/wn.svg
new file mode 100644 (file)
index 0000000..8bf5d89
--- /dev/null
@@ -0,0 +1,4 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1756 1774q-1 0 2-54t3-118q1-125 0-258t-36-267q-34-128-75-218t-89-157q-72-108-196-183t-259-98q9 49 8 96-2 36-34 36-37 0-33-36 3-132-94-226-76 80-82 186-2 35-36 31-32-1-32-37 0 0 2-8-41 13-86 37-29 20-47-10t16-47q43-22 65-33-86-88-196-142 12 139 76 263 17 26-8 46-28 22-47-7-7-10-20-36-21 21-28 31-7 9-24 40t-26 51q-9 25-8 40t3 35q-9 59-40 111t-81 127q-47 72-72 108t-38 92q-9 34 0 82t39 76q46 47 89 43 14 0 37-11t37-42q26-57 43-57 25 0 27 28 0 6-16 50-9 20-24 42-19 26-17 22 16 57 53 20 11-11 25-41t44-81q35-59 75-96t71-60q18-13 44-30t70-35q35-14 77-34t76-53q46-45 71-111 13-37 10-91-9-34 34-34 32 0 36 33 0 113-64 206 21 64 11 140-9 61-42 130t-136 155q-207 172-196 354 0 0 170 0t321 0h547z" fill-rule="nonzero" display="block" fill="#fff"/>
+ <path style="color:black;" d="m697 1359q13-20 10-42-10-64-71-54-18 3-29 12-4-5-12-22-11-32-42-22-31 12-24 45 45 115 163 158 34 10 45-20 12-32-18-44-6-3-11-5t-11-6zm-297-477q-29-18-35-48 1-33-31-36-35-4-36 30 4 66 59 105 26 21 48-4 22-27-5-47zm679 815q157-10 291-81t228-182q66-78 124-188t94-233q40-143 50-300t11-292v-218t-155 0-404 0h-671q-9 0-9 49t7 79q4 24 19 68t50 107q16 32 76 93t138 143q45 46 70 116t22 127q-37-30-81-49-212-76-307-220-7-9-45-81-20-38-34-52-19-19-55-21-56-3-87 54-42-12-75-10-56 21-81 45-51 51-66 102t-16 110q0 84 104 222 122 159 130 242 0 36 7 81 6 31 25 60 13 20 17 27t17 23q9 12 15 18t15 18q11 13 28 30-53 146-43 301 199-71 334-223 33 113 130 183 80-56 127-148zm677-1423q-1 0 2 54t3 118q1 125 0 258t-36 267q-34 128-75 218t-89 157q-72 108-196 183t-259 98q9-49 8-96-2-36-34-36-37 0-33 36 3 132-94 226-76-80-82-186-2-35-36-31-32 1-32 37 0 0 2 8-41-13-86-37-29-20-47 10t16 47q43 22 65 33-86 88-196 142 12-139 76-263 17-26-8-46-28-22-47 7-7 10-20 36-21-21-28-31-7-9-24-40t-26-51q-9-25-8-40t3-35q-9-59-40-111t-81-127q-47-72-72-108t-38-92q-9-34 0-82t39-76q46-47 89-43 14 0 37 11t37 42q26 57 43 57 25 0 27-28 0-6-16-50-9-20-24-42-19-26-17-22 16-57 53-20 11 11 25 41t44 81q35 59 75 96t71 60q18 13 44 30t70 35q35 14 77 34t76 53q46 45 71 111 13 37 10 91-9 34 34 34 32 0 36-33 0-113-64-206 21-64 11-140-9-61-42-130t-136-155q-207-172-196-354 0 0 170 0t321 0h547z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+</svg>
diff --git a/public/images/pieces/wp.svg b/public/images/pieces/wp.svg
new file mode 100644 (file)
index 0000000..eccfc27
--- /dev/null
@@ -0,0 +1,4 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1024 273h491q21 72 21 141 0 156-86 283t-223 187q-66 5-66 72 0 53 67 78 93 65 93 172 0 77-52 135t-126 67q-60 5-60 68 0 28 22 52 54 42 54 110 0 56-40 96t-95 40q-57 0-96-40t-40-96q0-67 54-110 22-22 22-52 0-63-59-68-75-9-126-67t-52-135q0-107 93-172 67-26 67-78 0-67-67-72-136-60-222-187t-86-283q0-74 21-141h491zm0-68h-540q-40 100-40 209 0 185 105 332t270 210q-71 33-115 99t-45 151q0 105 70 182t172 89q-81 61-81 161 0 84 59 144t145 60q84 0 144-60t60-144q0-100-81-161 102-12 172-89t70-182q0-84-45-150t-116-100q165-63 270-210t105-332q0-108-39-209h-540z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <path style="color:black;" d="m1024 1775h491q21-72 21-141 0-156-86-283t-223-187q-66-5-66-72 0-53 67-78 93-65 93-172 0-77-52-135t-126-67q-60-5-60-68 0-28 22-52 54-42 54-110 0-56-40-96t-95-40q-57 0-96 40t-40 96q0 67 54 110 22 22 22 52 0 63-59 68-75 9-126 67t-52 135q0 107 93 172 67 26 67 78 0 67-67 72-136 60-222 187t-86 283q0 74 21 141h491z" fill-rule="nonzero" display="block" fill="#fff"/>
+</svg>
diff --git a/public/images/pieces/wq.svg b/public/images/pieces/wq.svg
new file mode 100644 (file)
index 0000000..b98b76f
--- /dev/null
@@ -0,0 +1,19 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1024 1621q-57 0-96 40t-40 97q0 56 39 96t97 40q56 0 96-40t41-96q0-57-40-97t-97-40zm0 70q67 0 67 67 0 66-67 66-66 0-66-66 0-67 66-67zm509-1007q-193 49-505 49-320 0-511-50l15-96q195 46 496 46 299 0 488-45l17 96zm25 60 65 115q-48-19-98-19-134 0-214 109-60-50-134-50-96 0-153 75-64-70-153-70-72 0-132 49-84-107-217-107-51 0-101 19l70-120q194 56 533 56 345 0 534-57zm-448 239-85 489-85-483q3 2 14 10 23 45 70 45 51 0 66-45 6-6 20-16zm277-19v463l-165-454q19 7 32 18 20 25 54 25 40 0 64-35 3-4 7-8t8-9zm-562 14-164 449v-457q3 4 9 10 20 42 66 42 38 0 62-32 27-12 27-12zm-254-56-215 371 55-338q57-40 111-40 21 0 49 7zm903-5q23-7 51-7 61 0 114 38l55 346-220-377zm60-506-30 113q-196 43-480 43-281 0-479-43l-31-114q186 56 511 56 317 0 509-55zm106-128q-49-43-220-72t-394-29q-227 0-399 30t-217 75l63 240-28 157-88 153-85 622 49 19 274-462 6 550 68 12 209-553 112 595h69l112-593 207 551 69-12 6-550 275 463 47-22-83-619-89-153-28-159 65-243zm-81 36q-183 76-531 76-355 0-537-78 175-69 534-69 172 0 314 19t220 52zm-955 1252q-57 0-97 39t-40 97q0 56 40 96t97 40q56 0 96-40t40-96q0-57-40-96t-96-40zm0 70q66 0 66 66t-66 66q-67 0-67-66t67-66zm840 0q67 0 67 66t-67 66q-66 0-66-66t66-66zm0-70q-57 0-96 39t-40 97q0 56 39 96t97 40q57 0 97-40t40-96q0-57-40-96t-97-40zm-1208-110q-57 0-96 39t-40 97q0 56 39 96t97 41q57 0 97-40t40-97-40-96-97-40zm0 70q67 0 67 66 0 67-67 67-66 0-66-67 0-66 66-66zm1578 0q66 0 66 66 0 67-66 67-67 0-67-67 0-66 67-66zm0-70q-57 0-97 39t-40 97q0 56 40 96t97 41q56 0 96-40t40-97-40-96-96-40z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1024 357q67 0 67-67 0-66-67-66-66 0-66 66 0 67 66 67z" display="block"/>
+  <path style="color:black;" d="m1533 1364q-193-49-505-49-320 0-511 50l15 96q195-46 496-46 299 0 488 45l17-96z" display="block"/>
+  <path style="color:black;" d="m1558 1304 65-115q-48 19-98 19-134 0-214-109-60 50-134 50-96 0-153-75-64 70-153 70-72 0-132-49-84 107-217 107-51 0-101-19l70 120q194-56 533-56 345 0 534 57z" display="block"/>
+  <path style="color:black;" d="m1110 1065-85-489-85 483q3-2 14-10 23-45 70-45 51 0 66 45 6 6 20 16z" display="block"/>
+  <path style="color:black;" d="m1387 1084v-463l-165 454q19-7 32-18 20-25 54-25 40 0 64 35 3 4 7 8t8 9z" display="block"/>
+  <path style="color:black;" d="m825 1070-164-449v457q3-4 9-10 20-42 66-42 38 0 62 32 27 12 27 12z" display="block"/>
+  <path style="color:black;" d="m571 1126-215-371 55 338q57 40 111 40 21 0 49-7z" display="block"/>
+  <path style="color:black;" d="m1474 1131q23 7 51 7 61 0 114-38l55-346-220 377z" display="block"/>
+  <path style="color:black;" d="m1534 1637-30-113q-196-43-480-43-281 0-479 43l-31 114q186-56 511-56 317 0 509 55z" display="block"/>
+  <path style="color:black;" d="m1559 1729q-183-76-531-76-355 0-537 78 175 69 534 69 172 0 314-19t220-52z" display="block"/>
+  <path style="color:black;" d="m604 407q66 0 66-66t-66-66q-67 0-67 66t67 66z" display="block"/>
+  <path style="color:black;" d="m1444 407q67 0 67-66t-67-66q-66 0-66 66t66 66z" display="block"/>
+  <path style="color:black;" d="m236 517q67 0 67-66 0-67-67-67-66 0-66 67 0 66 66 66z" display="block"/>
+  <path style="color:black;" d="m1814 517q66 0 66-66 0-67-66-67-67 0-67 67 0 66 67 66z" display="block"/>
+ </g>
+</svg>
diff --git a/public/images/pieces/wr.svg b/public/images/pieces/wr.svg
new file mode 100644 (file)
index 0000000..d2a6ea2
--- /dev/null
@@ -0,0 +1,11 @@
+<svg xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns="http://www.w3.org/2000/svg" height="100%" width="100%" version="1.1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" viewBox="0 0 2048 2048">
+ <path style="color:black;" d="m1161 1706h170v137h274v-375l-222-171v-478l170-170v-205h153v-239h-1365v239h153v205l171 170v478l-222 171v375h273v-137h171v137h274v-137zm478-1330h-1230v-103h1230v103zm-155 204h-920v-136h920v136zm-170 717h-580v-478h580v478zm222 239v239h-137v-137h-308v137h-135v-137h-307v137h-137v-239h1024zm-77-887l-103 102h-663l-105-102h871zm-110 716l127 103h-904l128-103h649z" fill-rule="nonzero" transform="translate(0,2048) scale(1,-1)" display="block" fill="#000"/>
+ <g fill-rule="nonzero" fill="#fff">
+  <path style="color:black;" d="m1639 1672h-1230v103h1230v-103z" display="block"/>
+  <path style="color:black;" d="m1484 1468h-920v136h920v-136z" display="block"/>
+  <path style="color:black;" d="m1314 751h-580v478h580v-478z" display="block"/>
+  <path style="color:black;" d="m1536 512v-239h-137v137h-308v-137h-135v137h-307v-137h-137v239h1024z" display="block"/>
+ </g>
+ <path style="color:black;" d="m1459 1399-103-102h-663l-105 102h871z" fill-rule="nonzero" display="block" fill="#fff"/>
+ <path style="color:black;" d="m1349 683 127-103h-904l128 103h649z" fill-rule="nonzero" display="block" fill="#fff"/>
+</svg>
diff --git a/public/images/tmp_checkered/cb.png b/public/images/tmp_checkered/cb.png
new file mode 100644 (file)
index 0000000..4b083b3
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat bf0baedc348360c1bcc55b5b097f33455282cfe3                 1190
diff --git a/public/images/tmp_checkered/cn.png b/public/images/tmp_checkered/cn.png
new file mode 100644 (file)
index 0000000..da66450
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat c51c0fb1ada5645f4a51d64a4ddd6c835489cacf                 1269
diff --git a/public/images/tmp_checkered/cp.png b/public/images/tmp_checkered/cp.png
new file mode 100644 (file)
index 0000000..1a40e28
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat df06caec58e7d04178841eff04abe8c5241273c1                  837
diff --git a/public/images/tmp_checkered/cq.png b/public/images/tmp_checkered/cq.png
new file mode 100644 (file)
index 0000000..7abbafc
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat f0820c65df52f4b1152d1e409eb0a31818e456f7                 1573
diff --git a/public/images/tmp_checkered/cr.png b/public/images/tmp_checkered/cr.png
new file mode 100644 (file)
index 0000000..b140ac8
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat 8690188261dce5f318ce58fb7a653241be328cc4                  734
diff --git a/public/images/tmp_checkered/no_ck.png b/public/images/tmp_checkered/no_ck.png
new file mode 100644 (file)
index 0000000..eab00a8
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat c69fae7f8cc34d22b0be52be43f532e89d4397a2                 2099
diff --git a/public/javascripts/base_rules.js b/public/javascripts/base_rules.js
new file mode 100644 (file)
index 0000000..576bdd9
--- /dev/null
@@ -0,0 +1,1010 @@
+class PiPo //Piece+Position
+{
+       // o: {piece[p], color[c], posX[x], posY[y]}
+       constructor(o)
+       {
+               this.p = o.p;
+               this.c = o.c;
+               this.x = o.x;
+               this.y = o.y;
+       }
+}
+
+class Move
+{
+       // o: {appear, vanish, [start,] [end,]}
+       // appear,vanish = arrays of PiPo
+       // start,end = coordinates to apply to trigger move visually (think castle)
+       constructor(o)
+       {
+               this.appear = o.appear;
+               this.vanish = o.vanish;
+               this.start = !!o.start ? o.start : {x:o.vanish[0].x, y:o.vanish[0].y};
+               this.end = !!o.end ? o.end : {x:o.appear[0].x, y:o.appear[0].y};
+       }
+}
+
+// NOTE: x coords = top to bottom; y = left to right (from white player perspective)
+class ChessRules
+{
+       // Path to pieces
+       static getPpath(b)
+       {
+               return b; //usual pieces in pieces/ folder
+       }
+       // Turn "wb" into "B" (for FEN)
+       static board2fen(b)
+       {
+               return b[0]=='w' ? b[1].toUpperCase() : b[1];
+       }
+       // Turn "p" into "bp" (for board)
+       static fen2board(f)
+       {
+               return f.charCodeAt()<=90 ? "w"+f.toLowerCase() : "b"+f;
+       }
+
+       /////////////////
+       // INITIALIZATION
+
+       // fen = "position flags epSquare movesCount"
+       constructor(fen)
+       {
+               this.moves = [];
+               // Use fen string to initialize variables, flags and board
+               this.initVariables(fen);
+               this.flags = VariantRules.GetFlags(fen);
+               this.board = VariantRules.GetBoard(fen);
+       }
+
+       initVariables(fen)
+       {
+               this.INIT_COL_KING = {'w':-1, 'b':-1};
+               this.INIT_COL_ROOK = {'w':[-1,-1], 'b':[-1,-1]};
+               this.kingPos = {'w':[-1,-1], 'b':[-1,-1]}; //respective squares of white and black king
+               const fenParts = fen.split(" ");
+               const position = fenParts[0].split("/");
+               for (let i=0; i<position.length; i++)
+               {
+                       let j = 0;
+                       while (j < position[i].length)
+                       {
+                               switch (position[i].charAt(j))
+                               {
+                                       case 'k':
+                                               this.kingPos['b'] = [i,j];
+                                               this.INIT_COL_KING['b'] = j;
+                                               break;
+                                       case 'K':
+                                               this.kingPos['w'] = [i,j];
+                                               this.INIT_COL_KING['w'] = j;
+                                               break;
+                                       case 'r':
+                                               if (this.INIT_COL_ROOK['b'][0] < 0)
+                                                       this.INIT_COL_ROOK['b'][0] = j;
+                                               else
+                                                       this.INIT_COL_ROOK['b'][1] = j;
+                                               break;
+                                       case 'R':
+                                               if (this.INIT_COL_ROOK['w'][0] < 0)
+                                                       this.INIT_COL_ROOK['w'][0] = j;
+                                               else
+                                                       this.INIT_COL_ROOK['w'][1] = j;
+                                               break;
+                                       default:
+                                               let num = parseInt(position[i].charAt(j));
+                                               if (!isNaN(num))
+                                                       j += (num-1);
+                               }
+                               j++;
+                       }
+               }
+               let epSq = undefined;
+               if (fenParts[2] != "-")
+               {
+                       const digits = fenParts[2].split(","); //3,2 ...
+                       epSq = { x:Number.parseInt(digits[0]), y:Number.parseInt(digits[1]) };
+               }
+               this.epSquares = [ epSq ];
+               this.movesCount = Number.parseInt(fenParts[3]);
+       }
+
+       // Turn diagram fen into double array ["wb","wp","bk",...]
+       static GetBoard(fen)
+       {
+               let rows = fen.split(" ")[0].split("/");
+               let [sizeX,sizeY] = VariantRules.size;
+               let board = doubleArray(sizeX, sizeY, "");
+               for (let i=0; i<rows.length; i++)
+               {
+                       let j = 0;
+                       for (let indexInRow = 0; indexInRow < rows[i].length; indexInRow++)
+                       {
+                               let character = rows[i][indexInRow];
+                               let num = parseInt(character);
+                               if (!isNaN(num))
+                                       j += num; //just shift j
+                               else //something at position i,j
+                                       board[i][j++] = VariantRules.fen2board(character);
+                       }
+               }
+               return board;
+       }
+
+       // Overridable: flags can change a lot
+       static GetFlags(fen)
+       {
+               // white a-castle, h-castle, black a-castle, h-castle
+               let flags = {'w': new Array(2), 'b': new Array(2)};
+               let fenFlags = fen.split(" ")[1]; //flags right after position
+               for (let i=0; i<4; i++)
+                       flags[i < 2 ? 'w' : 'b'][i%2] = (fenFlags.charAt(i) == '1');
+               return flags;
+       }
+
+       ///////////////////
+       // GETTERS, SETTERS
+
+       // Simple useful getters
+       static get size() { return [8,8]; }
+       // Two next functions return 'undefined' if called on empty square
+       getColor(i,j) { return this.board[i][j].charAt(0); }
+       getPiece(i,j) { return this.board[i][j].charAt(1); }
+
+       // Color
+       getOppCol(color) { return color=="w" ? "b" : "w"; }
+
+       get lastMove() {
+               const L = this.moves.length;
+               return L>0 ? this.moves[L-1] : null;
+       }
+       get turn() {
+               return this.movesCount%2==0 ? 'w' : 'b';
+       }
+
+       // Pieces codes
+       static get PAWN() { return 'p'; }
+       static get ROOK() { return 'r'; }
+       static get KNIGHT() { return 'n'; }
+       static get BISHOP() { return 'b'; }
+       static get QUEEN() { return 'q'; }
+       static get KING() { return 'k'; }
+
+       // Empty square
+       static get EMPTY() { return ''; }
+
+       // Some pieces movements
+       static get steps() {
+               return {
+                       'r': [ [-1,0],[1,0],[0,-1],[0,1] ],
+                       'n': [ [-1,-2],[-1,2],[1,-2],[1,2],[-2,-1],[-2,1],[2,-1],[2,1] ],
+                       'b': [ [-1,-1],[-1,1],[1,-1],[1,1] ],
+                       'q': [ [-1,0],[1,0],[0,-1],[0,1],[-1,-1],[-1,1],[1,-1],[1,1] ]
+               };
+       }
+
+       // En-passant square, if any
+       getEpSquare(move)
+       {
+               const [sx,sy,ex] = [move.start.x,move.start.y,move.end.x];
+               if (this.getPiece(sx,sy) == VariantRules.PAWN && Math.abs(sx - ex) == 2)
+               {
+                       return {
+                               x: (sx + ex)/2,
+                               y: sy
+                       };
+               }
+               return undefined; //default
+       }
+
+       // can color1 take color2?
+       canTake(color1, color2)
+       {
+               return color1 != color2;
+       }
+
+       ///////////////////
+       // MOVES GENERATION
+
+       // All possible moves from selected square (assumption: color is OK)
+       getPotentialMovesFrom([x,y])
+       {
+               let c = this.getColor(x,y);
+               // Fill possible moves according to piece type
+               switch (this.getPiece(x,y))
+               {
+                       case VariantRules.PAWN:
+                               return this.getPotentialPawnMoves(x,y,c);
+                       case VariantRules.ROOK:
+                               return this.getPotentialRookMoves(x,y,c);
+                       case VariantRules.KNIGHT:
+                               return this.getPotentialKnightMoves(x,y,c);
+                       case VariantRules.BISHOP:
+                               return this.getPotentialBishopMoves(x,y,c);
+                       case VariantRules.QUEEN:
+                               return this.getPotentialQueenMoves(x,y,c);
+                       case VariantRules.KING:
+                               return this.getPotentialKingMoves(x,y,c);
+               }
+       }
+
+       // Build a regular move from its initial and destination squares; tr: transformation
+       getBasicMove(sx, sy, ex, ey, tr)
+       {
+               var mv = new Move({
+                       appear: [
+                               new PiPo({
+                                       x: ex,
+                                       y: ey,
+                                       c: this.getColor(sx,sy),
+                                       p: !!tr ? tr : this.getPiece(sx,sy)
+                               })
+                       ],
+                       vanish: [
+                               new PiPo({
+                                       x: sx,
+                                       y: sy,
+                                       c: this.getColor(sx,sy),
+                                       p: this.getPiece(sx,sy)
+                               })
+                       ]
+               });
+
+               // The opponent piece disappears if we take it
+               if (this.board[ex][ey] != VariantRules.EMPTY)
+               {
+                       mv.vanish.push(
+                               new PiPo({
+                                       x: ex,
+                                       y: ey,
+                                       c: this.getColor(ex,ey),
+                                       p: this.getPiece(ex,ey)
+                               })
+                       );
+               }
+               return mv;
+       }
+
+       // Generic method to find possible moves of non-pawn pieces ("sliding or jumping")
+       getSlideNJumpMoves(x, y, color, steps, oneStep)
+       {
+               var moves = [];
+               let [sizeX,sizeY] = VariantRules.size;
+               outerLoop:
+               for (let step of steps)
+               {
+                       var i = x + step[0];
+                       var j = y + step[1];
+                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
+                               && this.board[i][j] == VariantRules.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, i, j));
+                               if (oneStep !== undefined)
+                                       continue outerLoop;
+                               i += step[0];
+                               j += step[1];
+                       }
+                       if (i>=0 && i<8 && j>=0 && j<8 && this.canTake(color, this.getColor(i,j)))
+                               moves.push(this.getBasicMove(x, y, i, j));
+               }
+               return moves;
+       }
+
+       // What are the pawn moves from square x,y considering color "color" ?
+       getPotentialPawnMoves(x, y, color)
+       {
+               var moves = [];
+               var V = VariantRules;
+               let [sizeX,sizeY] = VariantRules.size;
+               let shift = (color == "w" ? -1 : 1);
+               let startRank = (color == "w" ? sizeY-2 : 1);
+               let lastRank = (color == "w" ? 0 : sizeY-1);
+
+               if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
+               {
+                       // Normal moves
+                       if (this.board[x+shift][y] == V.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, x+shift, y));
+                               if (x==startRank && this.board[x+2*shift][y] == V.EMPTY)
+                               {
+                                       // Two squares jump
+                                       moves.push(this.getBasicMove(x, y, x+2*shift, y));
+                               }
+                       }
+                       // Captures
+                       if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1))
+                               && this.board[x+shift][y-1] != V.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, x+shift, y-1));
+                       }
+                       if (y<sizeY-1 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y+1))
+                               && this.board[x+shift][y+1] != V.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, x+shift, y+1));
+                       }
+               }
+
+               if (x+shift == lastRank)
+               {
+                       // Promotion
+                       let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+                       promotionPieces.forEach(p => {
+                               // Normal move
+                               if (this.board[x+shift][y] == V.EMPTY)
+                                       moves.push(this.getBasicMove(x, y, x+shift, y, p));
+                               // Captures
+                               if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1))
+                                       && this.board[x+shift][y-1] != V.EMPTY)
+                               {
+                                       moves.push(this.getBasicMove(x, y, x+shift, y-1, p));
+                               }
+                               if (y<sizeY-1 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y+1))
+                                       && this.board[x+shift][y+1] != V.EMPTY)
+                               {
+                                       moves.push(this.getBasicMove(x, y, x+shift, y+1, p));
+                               }
+                       });
+               }
+
+               // En passant
+               const Lep = this.epSquares.length;
+               const epSquare = Lep>0 ? this.epSquares[Lep-1] : undefined;
+               if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1)
+               {
+                       let epStep = epSquare.y - y;
+                       var enpassantMove = this.getBasicMove(x, y, x+shift, y+epStep);
+                       enpassantMove.vanish.push({
+                               x: x,
+                               y: y+epStep,
+                               p: 'p',
+                               c: this.getColor(x,y+epStep)
+                       });
+                       moves.push(enpassantMove);
+               }
+
+               return moves;
+       }
+
+       // What are the rook moves from square x,y ?
+       getPotentialRookMoves(x, y, color)
+       {
+               return this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.ROOK]);
+       }
+
+       // What are the knight moves from square x,y ?
+       getPotentialKnightMoves(x, y, color)
+       {
+               return this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+       }
+
+       // What are the bishop moves from square x,y ?
+       getPotentialBishopMoves(x, y, color)
+       {
+               return this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.BISHOP]);
+       }
+
+       // What are the queen moves from square x,y ?
+       getPotentialQueenMoves(x, y, color)
+       {
+               return this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.QUEEN]);
+       }
+
+       // What are the king moves from square x,y ?
+       getPotentialKingMoves(x, y, c)
+       {
+               // Initialize with normal moves
+               var moves = this.getSlideNJumpMoves(x, y, c,
+                       VariantRules.steps[VariantRules.QUEEN], "oneStep");
+
+               return moves.concat(this.getCastleMoves(x,y,c));
+       }
+
+       getCastleMoves(x,y,c)
+       {
+               if (x != (c=="w" ? 7 : 0) || y != this.INIT_COL_KING[c])
+                       return []; //x isn't first rank, or king has moved (shortcut)
+
+               const V = VariantRules;
+
+               // Castling ?
+               const oppCol = this.getOppCol(c);
+               let moves = [];
+               let i = 0;
+               const finalSquares = [ [2,3], [6,5] ]; //king, then rook
+               castlingCheck:
+               for (let castleSide=0; castleSide < 2; castleSide++) //large, then small
+               {
+                       if (!this.flags[c][castleSide])
+                               continue;
+                       // If this code is reached, rooks and king are on initial position
+
+                       // Nothing on the path of the king (and no checks; OK also if y==finalSquare)?
+                       let step = finalSquares[castleSide][0] < y ? -1 : 1;
+                       for (i=y; i!=finalSquares[castleSide][0]; i+=step)
+                       {
+                               if (this.isAttacked([x,i], oppCol) || (this.board[x][i] != V.EMPTY &&
+                                       // NOTE: next check is enough, because of chessboard constraints
+                                       (this.getColor(x,i) != c || ![V.KING,V.ROOK].includes(this.getPiece(x,i)))))
+                               {
+                                       continue castlingCheck;
+                               }
+                       }
+
+                       // Nothing on the path to the rook?
+                       step = castleSide == 0 ? -1 : 1;
+                       for (i = y + step; i != this.INIT_COL_ROOK[c][castleSide]; i += step)
+                       {
+                               if (this.board[x][i] != V.EMPTY)
+                                       continue castlingCheck;
+                       }
+                       const rookPos = this.INIT_COL_ROOK[c][castleSide];
+
+                       // Nothing on final squares, except maybe king and castling rook?
+                       for (i=0; i<2; i++)
+                       {
+                               if (this.board[x][finalSquares[castleSide][i]] != V.EMPTY &&
+                                       this.getPiece(x,finalSquares[castleSide][i]) != V.KING &&
+                                       finalSquares[castleSide][i] != rookPos)
+                               {
+                                       continue castlingCheck;
+                               }
+                       }
+
+                       // If this code is reached, castle is valid
+                       moves.push( new Move({
+                               appear: [
+                                       new PiPo({x:x,y:finalSquares[castleSide][0],p:V.KING,c:c}),
+                                       new PiPo({x:x,y:finalSquares[castleSide][1],p:V.ROOK,c:c})],
+                               vanish: [
+                                       new PiPo({x:x,y:y,p:V.KING,c:c}),
+                                       new PiPo({x:x,y:rookPos,p:V.ROOK,c:c})],
+                               end: Math.abs(y - rookPos) <= 2
+                                       ? {x:x, y:rookPos}
+                                       : {x:x, y:y + 2 * (castleSide==0 ? -1 : 1)}
+                       }) );
+               }
+
+               return moves;
+       }
+
+       ///////////////////
+       // MOVES VALIDATION
+
+       canIplay(color, sq)
+       {
+               return ((color=='w' && this.movesCount%2==0)
+                               || (color=='b' && this.movesCount%2==1))
+                       && this.getColor(sq[0], sq[1]) == color;
+       }
+
+       getPossibleMovesFrom(sq)
+       {
+               // Assuming color is right (already checked)
+               return this.filterValid( this.getPotentialMovesFrom(sq) );
+       }
+
+       // TODO: once a promotion is filtered, the others results are same: useless computations
+       filterValid(moves)
+       {
+               if (moves.length == 0)
+                       return [];
+               let color = this.getColor( moves[0].start.x, moves[0].start.y );
+               return moves.filter(m => {
+                       return !this.underCheck(m, color);
+               });
+       }
+
+       // Search for all valid moves considering current turn (for engine and game end)
+       getAllValidMoves(color)
+       {
+               const oppCol = this.getOppCol(color);
+               var potentialMoves = [];
+               let [sizeX,sizeY] = VariantRules.size;
+               for (var i=0; i<sizeX; i++)
+               {
+                       for (var j=0; j<sizeY; j++)
+                       {
+                               // Next condition ... != oppCol is a little HACK to work with checkered variant
+                               if (this.board[i][j] != VariantRules.EMPTY && this.getColor(i,j) != oppCol)
+                                       Array.prototype.push.apply(potentialMoves, this.getPotentialMovesFrom([i,j]));
+                       }
+               }
+               // NOTE: prefer lazy undercheck tests, letting the king being taken?
+               // No: if happen on last 1/2 move, could lead to forbidden moves, wrong evals
+               return this.filterValid(potentialMoves);
+       }
+
+       // Check if pieces of color 'color' are attacking square x,y
+       isAttacked(sq, color)
+       {
+               return (this.isAttackedByPawn(sq, color)
+                       || this.isAttackedByRook(sq, color)
+                       || this.isAttackedByKnight(sq, color)
+                       || this.isAttackedByBishop(sq, color)
+                       || this.isAttackedByQueen(sq, color)
+                       || this.isAttackedByKing(sq, color));
+       }
+
+       // Is square x,y attacked by pawns of color c ?
+       isAttackedByPawn([x,y], c)
+       {
+               let pawnShift = (c=="w" ? 1 : -1);
+               if (x+pawnShift>=0 && x+pawnShift<8)
+               {
+                       for (let i of [-1,1])
+                       {
+                               if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN
+                                       && this.getColor(x+pawnShift,y+i)==c)
+                               {
+                                       return true;
+                               }
+                       }
+               }
+               return false;
+       }
+
+       // Is square x,y attacked by rooks of color c ?
+       isAttackedByRook(sq, color)
+       {
+               return this.isAttackedBySlideNJump(sq, color,
+                       VariantRules.ROOK, VariantRules.steps[VariantRules.ROOK]);
+       }
+
+       // Is square x,y attacked by knights of color c ?
+       isAttackedByKnight(sq, color)
+       {
+               return this.isAttackedBySlideNJump(sq, color,
+                       VariantRules.KNIGHT, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+       }
+
+       // Is square x,y attacked by bishops of color c ?
+       isAttackedByBishop(sq, color)
+       {
+               return this.isAttackedBySlideNJump(sq, color,
+                       VariantRules.BISHOP, VariantRules.steps[VariantRules.BISHOP]);
+       }
+
+       // Is square x,y attacked by queens of color c ?
+       isAttackedByQueen(sq, color)
+       {
+               return this.isAttackedBySlideNJump(sq, color,
+                       VariantRules.QUEEN, VariantRules.steps[VariantRules.QUEEN]);
+       }
+
+       // Is square x,y attacked by king of color c ?
+       isAttackedByKing(sq, color)
+       {
+               return this.isAttackedBySlideNJump(sq, color,
+                       VariantRules.KING, VariantRules.steps[VariantRules.QUEEN], "oneStep");
+       }
+
+       // Generic method for non-pawn pieces ("sliding or jumping"): is x,y attacked by piece != color ?
+       isAttackedBySlideNJump([x,y], c,piece,steps,oneStep)
+       {
+               for (let step of steps)
+               {
+                       let rx = x+step[0], ry = y+step[1];
+                       while (rx>=0 && rx<8 && ry>=0 && ry<8 && this.board[rx][ry] == VariantRules.EMPTY
+                               && !oneStep)
+                       {
+                               rx += step[0];
+                               ry += step[1];
+                       }
+                       if (rx>=0 && rx<8 && ry>=0 && ry<8 && this.board[rx][ry] != VariantRules.EMPTY
+                               && this.getPiece(rx,ry) == piece && this.getColor(rx,ry) == c)
+                       {
+                               return true;
+                       }
+               }
+               return false;
+       }
+
+       underCheck(move, c)
+       {
+               this.play(move);
+               let res = this.isAttacked(this.kingPos[c], this.getOppCol(c));
+               this.undo(move);
+               return res;
+       }
+
+       // Apply a move on board
+       static PlayOnBoard(board, move)
+       {
+               for (let psq of move.vanish)
+                       board[psq.x][psq.y] = VariantRules.EMPTY;
+               for (let psq of move.appear)
+                       board[psq.x][psq.y] = psq.c + psq.p;
+       }
+       // Un-apply the played move
+       static UndoOnBoard(board, move)
+       {
+               for (let psq of move.appear)
+                       board[psq.x][psq.y] = VariantRules.EMPTY;
+               for (let psq of move.vanish)
+                       board[psq.x][psq.y] = psq.c + psq.p;
+       }
+
+       // Before move is played:
+       updateVariables(move)
+       {
+               const piece = this.getPiece(move.start.x,move.start.y);
+               const c = this.getColor(move.start.x,move.start.y);
+               const firstRank = (c == "w" ? 7 : 0);
+
+               // Update king position + flags
+               if (piece == VariantRules.KING && move.appear.length > 0)
+               {
+                       this.kingPos[c][0] = move.appear[0].x;
+                       this.kingPos[c][1] = move.appear[0].y;
+                       this.flags[c] = [false,false];
+                       return;
+               }
+               const oppCol = this.getOppCol(c);
+               const oppFirstRank = 7 - firstRank;
+               if (move.start.x == firstRank //our rook moves?
+                       && this.INIT_COL_ROOK[c].includes(move.start.y))
+               {
+                       const flagIdx = move.start.y == this.INIT_COL_ROOK[c][0] ? 0 : 1;
+                       this.flags[c][flagIdx] = false;
+               }
+               else if (move.end.x == oppFirstRank //we took opponent rook?
+                       && this.INIT_COL_ROOK[c].includes(move.end.y))
+               {
+                       const flagIdx = move.end.y == this.INIT_COL_ROOK[oppCol][0] ? 0 : 1;
+                       this.flags[oppCol][flagIdx] = false;
+               }
+       }
+
+       play(move, ingame)
+       {
+               // Save flags (for undo)
+               move.flags = JSON.stringify(this.flags); //TODO: less costly
+               this.updateVariables(move);
+
+               this.epSquares.push( this.getEpSquare(move) );
+               VariantRules.PlayOnBoard(this.board, move);
+               this.movesCount++;
+
+               if (!!ingame)
+                       this.moves.push(move);
+       }
+
+       undo(move)
+       {
+               VariantRules.UndoOnBoard(this.board, move);
+               this.epSquares.pop();
+               this.movesCount--;
+
+               // Update king position, and reset stored/computed flags
+               const c = this.getColor(move.start.x,move.start.y);
+               if (this.getPiece(move.start.x,move.start.y) == VariantRules.KING)
+                       this.kingPos[c] = [move.start.x, move.start.y];
+
+               this.flags = JSON.parse(move.flags);
+       }
+
+       //////////////
+       // END OF GAME
+
+       checkGameOver(color)
+       {
+               // Check for 3 repetitions
+               if (this.moves.length >= 8)
+               {
+                       // NOTE: crude detection, only moves repetition
+                       const L = this.moves.length;
+                       if (_.isEqual(this.moves[L-1], this.moves[L-5]) &&
+                               _.isEqual(this.moves[L-2], this.moves[L-6]) &&
+                               _.isEqual(this.moves[L-3], this.moves[L-7]) &&
+                               _.isEqual(this.moves[L-4], this.moves[L-8]))
+                       {
+                               return "1/2 (repetition)";
+                       }
+               }
+
+               // TODO: not required to generate ALL: just need one (callback ? hook ? ...)
+               if (this.getAllValidMoves(color).length > 0)
+               {
+                       // game not over
+                       return "*";
+               }
+
+               // Game over
+               return this.checkGameEnd(color);
+       }
+
+       // Useful stand-alone for engine
+       checkGameEnd(color)
+       {
+               // No valid move: stalemate or checkmate?
+               if (!this.isAttacked(this.kingPos[color], this.getOppCol(color)))
+                       return "1/2";
+               // OK, checkmate
+               return color == "w" ? "0-1" : "1-0";
+       }
+
+       ////////
+       //ENGINE
+
+       // Pieces values
+       static get VALUES() {
+               return {
+                       'p': 1,
+                       'r': 5,
+                       'n': 3,
+                       'b': 3,
+                       'q': 9,
+                       'k': 1000
+               };
+       }
+
+       // Assumption: at least one legal move
+       getComputerMove(color)
+       {
+               const oppCol = this.getOppCol(color);
+
+               // Rank moves using a min-max at depth 2
+               let moves1 = this.getAllValidMoves(color);
+
+               for (let i=0; i<moves1.length; i++)
+               {
+                       moves1[i].eval = (color=="w" ? -1 : 1) * 1000; //very low, I'm checkmated
+                       let eval2 = (color=="w" ? 1 : -1) * 1000; //initialized with very high (checkmate) value
+                       this.play(moves1[i]);
+                       // Second half-move:
+                       let moves2 = this.getAllValidMoves(oppCol);
+                       // If no possible moves AND underCheck, eval2 is correct.
+                       // If !underCheck, eval2 is 0 (stalemate).
+                       if (moves2.length == 0 && this.checkGameEnd(oppCol) == "1/2")
+                               eval2 = 0;
+                       for (let j=0; j<moves2.length; j++)
+                       {
+                               this.play(moves2[j]);
+                               let evalPos = this.evalPosition();
+                               if ((color == "w" && evalPos < eval2) || (color=="b" && evalPos > eval2))
+                                       eval2 = evalPos;
+                               this.undo(moves2[j]);
+                       }
+                       if ((color=="w" && eval2 > moves1[i].eval) || (color=="b" && eval2 < moves1[i].eval))
+                               moves1[i].eval = eval2;
+                       this.undo(moves1[i]);
+               }
+               moves1.sort( (a,b) => { return (color=="w" ? 1 : -1) * (b.eval - a.eval); });
+
+               // TODO: show current analyzed move for depth 3, allow stopping eval (return moves1[0])
+//             for (let i=0; i<moves1.length; i++)
+//             {
+//                     this.play(moves1[i]);
+//                     // 0.1 * oldEval : heuristic to avoid some bad moves (not all...)
+//                     moves1[i].eval = 0.1*moves1[i].eval + this.alphabeta(oppCol, color, 2, -1000, 1000);
+//                     this.undo(moves1[i]);
+//             }
+//             moves1.sort( (a,b) => { return (color=="w" ? 1 : -1) * (b.eval - a.eval); });
+
+               let candidates = [0]; //indices of candidates moves
+               for (let j=1; j<moves1.length && moves1[j].eval == moves1[0].eval; j++)
+                       candidates.push(j);
+
+               //console.log(moves1.map(m => { return [this.getNotation(m), m.eval]; }));
+               return moves1[_.sample(candidates, 1)];
+       }
+
+       alphabeta(color, oppCol, depth, alpha, beta)
+  {
+               let moves = this.getAllValidMoves(color);
+               if (moves.length == 0)
+               {
+                       switch (this.checkGameEnd(color))
+                       {
+                               case "1/2": return 0;
+                               default: return color=="w" ? -1000 : 1000;
+                       }
+               }
+               if (depth == 0)
+      return this.evalPosition();
+    let v = color=="w" ? -1000 : 1000;
+               if (color == "w")
+               {
+                       for (let i=0; i<moves.length; i++)
+      {
+                               this.play(moves[i]);
+                               v = Math.max(v, this.alphabeta(oppCol, color, depth-1, alpha, beta));
+                               this.undo(moves[i]);
+                               alpha = Math.max(alpha, v);
+                               if (alpha >= beta)
+                                       break; //beta cutoff
+                       }
+               }
+               else //color=="b"
+               {
+                       for (let i=0; i<moves.length; i++)
+                       {
+                               this.play(moves[i]);
+                               v = Math.min(v, this.alphabeta(oppCol, color, depth-1, alpha, beta));
+                               this.undo(moves[i]);
+                               beta = Math.min(beta, v);
+                               if (alpha >= beta)
+                                       break; //alpha cutoff
+                       }
+               }
+               return v;
+       }
+
+       evalPosition()
+       {
+               const [sizeX,sizeY] = VariantRules.size;
+               let evaluation = 0;
+               //Just count material for now
+               for (let i=0; i<sizeX; i++)
+               {
+                       for (let j=0; j<sizeY; j++)
+                       {
+                               if (this.board[i][j] != VariantRules.EMPTY)
+                               {
+                                       const sign = this.getColor(i,j) == "w" ? 1 : -1;
+                                       evaluation += sign * VariantRules.VALUES[this.getPiece(i,j)];
+                               }
+                       }
+               }
+               return evaluation;
+       }
+
+       ////////////
+       // FEN utils
+
+       // Overridable..
+       static GenRandInitFen()
+       {
+               let pieces = [new Array(8), new Array(8)];
+               // Shuffle pieces on first and last rank
+               for (let c = 0; c <= 1; c++)
+               {
+                       let positions = _.range(8);
+
+                       // Get random squares for bishops
+                       let randIndex = 2 * _.random(3);
+                       let bishop1Pos = positions[randIndex];
+                       // The second bishop must be on a square of different color
+                       let randIndex_tmp = 2 * _.random(3) + 1;
+                       let bishop2Pos = positions[randIndex_tmp];
+                       // Remove chosen squares
+                       positions.splice(Math.max(randIndex,randIndex_tmp), 1);
+                       positions.splice(Math.min(randIndex,randIndex_tmp), 1);
+
+                       // Get random squares for knights
+                       randIndex = _.random(5);
+                       let knight1Pos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+                       randIndex = _.random(4);
+                       let knight2Pos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+
+                       // Get random square for queen
+                       randIndex = _.random(3);
+                       let queenPos = positions[randIndex];
+                       positions.splice(randIndex, 1);
+
+                       // Rooks and king positions are now fixed, because of the ordering rook-king-rook
+                       let rook1Pos = positions[0];
+                       let kingPos = positions[1];
+                       let rook2Pos = positions[2];
+
+                       // Finally put the shuffled pieces in the board array
+                       pieces[c][rook1Pos] = 'r';
+                       pieces[c][knight1Pos] = 'n';
+                       pieces[c][bishop1Pos] = 'b';
+                       pieces[c][queenPos] = 'q';
+                       pieces[c][kingPos] = 'k';
+                       pieces[c][bishop2Pos] = 'b';
+                       pieces[c][knight2Pos] = 'n';
+                       pieces[c][rook2Pos] = 'r';
+               }
+               let fen = pieces[0].join("") +
+                       "/pppppppp/8/8/8/8/PPPPPPPP/" +
+                       pieces[1].join("").toUpperCase() +
+                       " 1111 - 0"; //flags + enPassant + movesCount
+               return fen;
+       }
+
+       // Return current fen according to pieces+colors state
+       getFen()
+       {
+               const L = this.epSquares.length;
+               const epSq = this.epSquares[L-1]===undefined
+                       ? "-"
+                       : this.epSquares[L-1].x+","+this.epSquares[L-1].y;
+               return this.getBaseFen() + " " + this.getFlagsFen()
+                       + " " + epSq + " " + this.movesCount;
+       }
+
+       getBaseFen()
+       {
+               let fen = "";
+               let [sizeX,sizeY] = VariantRules.size;
+               for (let i=0; i<sizeX; i++)
+               {
+                       let emptyCount = 0;
+                       for (let j=0; j<sizeY; j++)
+                       {
+                               if (this.board[i][j] == VariantRules.EMPTY)
+                                       emptyCount++;
+                               else
+                               {
+                                       if (emptyCount > 0)
+                                       {
+                                               // Add empty squares in-between
+                                               fen += emptyCount;
+                                               emptyCount = 0;
+                                       }
+                                       fen += VariantRules.board2fen(this.board[i][j]);
+                               }
+                       }
+                       if (emptyCount > 0)
+                       {
+                               // "Flush remainder"
+                               fen += emptyCount;
+                       }
+                       if (i < sizeX - 1)
+                               fen += "/"; //separate rows
+               }
+               return fen;
+       }
+
+       // Overridable..
+       getFlagsFen()
+       {
+               let fen = "";
+               // Add castling flags
+               for (let i of ['w','b'])
+               {
+                       for (let j=0; j<2; j++)
+                               fen += this.flags[i][j] ? '1' : '0';
+               }
+               return fen;
+       }
+
+       // Context: just before move is played, turn hasn't changed
+       getNotation(move)
+       {
+               if (move.appear.length == 2)
+               {
+                       // Castle
+                       if (move.end.y < move.start.y)
+                               return "0-0-0";
+                       else
+                               return "0-0";
+               }
+
+               // Translate final square
+               let finalSquare =
+                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+
+               let piece = this.getPiece(move.start.x, move.start.y);
+               if (piece == VariantRules.PAWN)
+               {
+                       // Pawn move
+                       let notation = "";
+                       if (move.vanish.length > 1)
+                       {
+                               // Capture
+                               let startColumn = String.fromCharCode(97 + move.start.y);
+                               notation = startColumn + "x" + finalSquare;
+                       }
+                       else //no capture
+                               notation = finalSquare;
+                       if (move.appear.length > 0 && piece != move.appear[0].p) //promotion
+                               notation += "=" + move.appear[0].p.toUpperCase();
+                       return notation;
+               }
+
+               else
+               {
+                       // Piece movement
+                       return piece.toUpperCase() + (move.vanish.length > 1 ? "x" : "") + finalSquare;
+               }
+       }
+}
diff --git a/public/javascripts/components/game.js b/public/javascripts/components/game.js
new file mode 100644 (file)
index 0000000..1338132
--- /dev/null
@@ -0,0 +1,542 @@
+Vue.component('my-game', {
+       data: function() {
+               return {
+                       vr: null, //object to check moves, store them, FEN..
+                       mycolor: "w",
+                       possibleMoves: [], //filled after each valid click/dragstart
+                       choices: [], //promotion pieces, or checkered captures... (contain possible pieces)
+                       start: {}, //pixels coordinates + id of starting square (click or drag)
+                       selectedPiece: null, //moving piece (or clicked piece)
+                       conn: null, //socket messages
+                       endofgame: "", //end of game message
+                       mode: "idle", //human, computer or idle (when not playing)
+                       oppid: "", //opponent ID in case of HH game
+                       oppConnected: false,
+               };
+       },
+       render(h) {
+               let [sizeX,sizeY] = VariantRules.size;
+               // Precompute hints squares to facilitate rendering
+               let hintSquares = doubleArray(sizeX, sizeY, false);
+               this.possibleMoves.forEach(m => { hintSquares[m.end.x][m.end.y] = true; });
+               let elementArray = [];
+               let square00 = document.getElementById("sq-0-0");
+               let squareWidth = !!square00
+                       ? parseFloat(window.getComputedStyle(square00).width.slice(0,-2))
+                       : 0;
+               let actionArray = [
+                       h('button',
+                               {
+                                       on: { click: () => this.newGame("human") },
+                                       attrs: { "aria-label": 'New game VS human' },
+                                       'class': { "tooltip":true },
+                               },
+                               [h('i', { 'class': { "material-icons": true } }, "accessibility")]),
+                       h('button',
+                               {
+                                       on: { click: () => this.newGame("computer") },
+                                       attrs: { "aria-label": 'New game VS computer' },
+                                       'class': { "tooltip":true },
+                               },
+                               [h('i', { 'class': { "material-icons": true } }, "computer")])
+               ];
+               if (!!this.vr)
+               {
+                       if (this.mode == "human")
+                       {
+                               let connectedIndic = h(
+                                       'div',
+                                       {
+                                               "class": {
+                                                       "connected": this.oppConnected,
+                                                       "disconnected": !this.oppConnected,
+                                               },
+                                       }
+                               );
+                               elementArray.push(connectedIndic);
+                       }
+                       let choices = h('div',
+                               {
+                                       attrs: { "id": "choices" },
+                                       'class': { 'row': true },
+                                       style: {
+                                               //"position": "relative",
+                                               "display": this.choices.length>0?"block":"none",
+                                               "top": "-" + ((sizeY/2)*squareWidth+squareWidth/2) + "px",
+                                               "width": (this.choices.length * squareWidth) + "px",
+                                               "height": squareWidth + "px",
+                                       },
+                               },
+                               this.choices.map( m => { //a "choice" is a move
+                                       return h('div',
+                                               {
+                                                       'class': { 'board': true },
+                                                       style: {
+                                                               'width': (100/this.choices.length) + "%",
+                                                               'padding-bottom': (100/this.choices.length) + "%",
+                                                       },
+                                               },
+                                               [h('img',
+                                                       {
+                                                               attrs: { "src": '/images/pieces/' + VariantRules.getPpath(m.appear[0].c+m.appear[0].p) + '.svg' },
+                                                               'class': { 'choice-piece': true, 'board': true },
+                                                               on: { "click": e => { this.play(m); this.choices=[]; } },
+                                                       })
+                                               ]
+                                       );
+                               })
+                       );
+                       // Create board element (+ reserves if needed by variant or mode)
+                       let gameDiv = h('div',
+                               {
+                                       'class': { 'game': true },
+                               },
+                               [_.range(sizeX).map(i => {
+                                       let ci = this.mycolor=='w' ? i : sizeX-i-1;
+                                       return h(
+                                               'div',
+                                               {
+                                                       'class': {
+                                                               'row': true,
+                                                       },
+                                                       style: { 'opacity': this.choices.length>0?"0.5":"1" },
+                                               },
+                                               _.range(sizeY).map(j => {
+                                                       let cj = this.mycolor=='w' ? j : sizeY-j-1;
+                                                       let elems = [];
+                                                       if (this.vr.board[ci][cj] != VariantRules.EMPTY)
+                                                       {
+                                                               elems.push(
+                                                                       h(
+                                                                               'img',
+                                                                               {
+                                                                                       'class': {
+                                                                                               'piece': true,
+                                                                                               'ghost': !!this.selectedPiece && this.selectedPiece.parentNode.id == "sq-"+ci+"-"+cj,
+                                                                                       },
+                                                                                       attrs: {
+                                                                                               src: "/images/pieces/" + VariantRules.getPpath(this.vr.board[ci][cj]) + ".svg",
+                                                                                       },
+                                                                               }
+                                                                       )
+                                                               );
+                                                       }
+                                                       if (hintSquares[ci][cj])
+                                                       {
+                                                               elems.push(
+                                                                       h(
+                                                                               'img',
+                                                                               {
+                                                                                       'class': {
+                                                                                               'mark-square': true,
+                                                                                       },
+                                                                                       attrs: {
+                                                                                               src: "/images/mark.svg",
+                                                                                       },
+                                                                               }
+                                                                       )
+                                                               );
+                                                       }
+                                                       const lm = this.vr.lastMove; //TODO: interruptions (FEN local storage..)
+                                                       const highlight = !!lm && _.isMatch(lm.end, {x:ci,y:cj}); //&& _.isMatch(lm.start, {x:ci,y:cj})
+                                                       return h(
+                                                               'div',
+                                                               {
+                                                                       'class': {
+                                                                               'board': true,
+                                                                               'light-square': !highlight && (i+j)%2==0,
+                                                                               'dark-square': !highlight && (i+j)%2==1,
+                                                                               'highlight': highlight,
+                                                                       },
+                                                                       attrs: {
+                                                                               id: this.getSquareId({x:ci,y:cj}),
+                                                                       },
+                                                               },
+                                                               elems
+                                                       );
+                                               })
+                                       );
+                               }), choices]
+                       );
+                       actionArray.push(
+                               h('button',
+                                       {
+                                               on: { click: this.resign },
+                                               attrs: { "aria-label": 'Resign' },
+                                               'class': { "tooltip":true },
+                                       },
+                                       [h('i', { 'class': { "material-icons": true } }, "flag")])
+                       );
+                       elementArray.push(gameDiv);
+       //                      if (!!vr.reserve)
+       //                      {
+       //                              let reserve = h('div',
+       //                                      {'class':{'game':true}}, [
+       //                                              h('div',
+       //                                                      { 'class': { 'row': true }},
+       //                                                      [
+       //                                                              h('div',
+       //                                                                      {'class':{'board':true}},
+       //                                                                      [h('img',{'class':{"piece":true},attrs:{"src":"/images/pieces/wb.svg"}})]
+       //                                                              )
+       //                                                      ]
+       //                                              )
+       //                                      ],
+       //                              );
+       //                              elementArray.push(reserve);
+       //                      }
+                       const modalEog = [
+                               h('input',
+                                       {
+                                               attrs: { "id": "modal-control", type: "checkbox" },
+                                               "class": { "modal": true },
+                                       }),
+                               h('div',
+                                       {
+                                               attrs: { "role": "dialog", "aria-labelledby": "dialog-title" },
+                                       },
+                                       [
+                                               h('div',
+                                                       {
+                                                               "class": { "card": true, "smallpad": true },
+                                                       },
+                                                       [
+                                                               h('label',
+                                                                       {
+                                                                               attrs: { "for": "modal-control" },
+                                                                               "class": { "modal-close": true },
+                                                                       }
+                                                               ),
+                                                               h('h3',
+                                                                       {
+                                                                               "class": { "section": true },
+                                                                               domProps: { innerHTML: "End of game" },
+                                                                       }
+                                                               ),
+                                                               h('p',
+                                                                       {
+                                                                               "class": { "section": true },
+                                                                               domProps: { innerHTML: this.endofgame },
+                                                                       }
+                                                               )
+                                                       ]
+                                               )
+                                       ]
+                               )
+                       ];
+                       elementArray = elementArray.concat(modalEog);
+               }
+               const modalNewgame = [
+                       h('input',
+                               {
+                                       attrs: { "id": "modal-control2", type: "checkbox" },
+                                       "class": { "modal": true },
+                               }),
+                       h('div',
+                               {
+                                       attrs: { "role": "dialog", "aria-labelledby": "dialog-title" },
+                               },
+                               [
+                                       h('div',
+                                               {
+                                                       "class": { "card": true, "smallpad": true },
+                                               },
+                                               [
+                                                       h('label',
+                                                               {
+                                                                       attrs: { "id": "close-newgame", "for": "modal-control2" },
+                                                                       "class": { "modal-close": true },
+                                                               }
+                                                       ),
+                                                       h('h3',
+                                                               {
+                                                                       "class": { "section": true },
+                                                                       domProps: { innerHTML: "New game" },
+                                                               }
+                                                       ),
+                                                       h('p',
+                                                               {
+                                                                       "class": { "section": true },
+                                                                       domProps: { innerHTML: "Waiting for opponent..." },
+                                                               }
+                                                       )
+                                               ]
+                                       )
+                               ]
+                       )
+               ];
+               elementArray = elementArray.concat(modalNewgame);
+               const actions = h('div',
+                       {
+                               attrs: { "id": "actions" },
+                               'class': { 'text-center': true },
+                       },
+                       actionArray
+               );
+               elementArray.push(actions);
+               return h(
+                       'div',
+                       {
+                               'class': {
+                                       "col-sm-12":true,
+                                       "col-md-8":true,
+                                       "col-md-offset-2":true,
+                                       "col-lg-6":true,
+                                       "col-lg-offset-3":true,
+                               },
+                               // NOTE: click = mousedown + mouseup --> what about smartphone?!
+                               on: {
+                                       mousedown: this.mousedown,
+                                       mousemove: this.mousemove,
+                                       mouseup: this.mouseup,
+                                       touchdown: this.mousedown,
+                                       touchmove: this.mousemove,
+                                       touchup: this.mouseup,
+                               },
+                       },
+                       elementArray
+               );
+       },
+       created: function() {
+               const url = socketUrl;
+               const continuation = (localStorage.getItem("variant") === variant);
+               this.myid = continuation
+                       ? localStorage.getItem("myid")
+                       // random enough (TODO: function)
+                       : (Date.now().toString(36) + Math.random().toString(36).substr(2, 7)).toUpperCase();
+               this.conn = new WebSocket(url + "/?sid=" + this.myid + "&page=" + variant);
+               this.conn.onopen = () => {
+                       if (continuation)
+                       {
+                               // TODO: check FEN integrity with opponent
+                               this.newGame("human", localStorage.getItem("fen"),
+                                       localStorage.getItem("mycolor"), localStorage.getItem("oppid"), true);
+                               // Send ping to server, which answers pong if opponent is connected
+                               this.conn.send(JSON.stringify({code:"ping", oppid:this.oppId}));
+                       }
+               };
+               this.conn.onmessage = msg => {
+                       const data = JSON.parse(msg.data);
+                       switch (data.code)
+                       {
+                               case "newgame": //opponent found
+                                       this.newGame("human", data.fen, data.color, data.oppid); //oppid: opponent socket ID
+                                       break;
+                               case "newmove": //..he played!
+                                       this.play(data.move, "animate");
+                                       break;
+                               case "pong": //sent when opponent stayed online after we disconnected
+                                       this.oppConnected = true;
+                                       break;
+                               case "resign": //..you won!
+                                       this.endGame("Victory!");
+                                       break;
+                               // TODO: also use (dis)connect info to count online players
+                               case "connect":
+                               case "disconnect":
+                                       if (this.mode == "human" && this.oppid == data.id)
+                                               this.oppConnected = (data.code == "connect");
+                                       break;
+                       }
+               };
+       },
+       methods: {
+               endGame: function(message) {
+                       this.endofgame = message;
+                       document.getElementById("modal-control").checked = true;
+                       if (this.mode == "human")
+                               this.clearStorage();
+                       this.mode = "idle";
+                       this.oppid = "";
+               },
+               resign: function() {
+                       if (this.mode == "human" && this.oppConnected)
+                               this.conn.send(JSON.stringify({code: "resign", oppid: this.oppid}));
+                       this.endGame("Try again!");
+               },
+               updateStorage: function() {
+                       if (!localStorage.getItem("myid"))
+                       {
+                               localStorage.setItem("myid", this.myid);
+                               localStorage.setItem("variant", variant);
+                               localStorage.setItem("mycolor", this.mycolor);
+                               localStorage.setItem("oppid", this.oppid);
+                       }
+                       localStorage.setItem("fen", this.vr.getFen());
+               },
+               clearStorage: function() {
+                       delete localStorage["variant"];
+                       delete localStorage["myid"];
+                       delete localStorage["mycolor"];
+                       delete localStorage["oppid"];
+                       delete localStorage["fen"];
+               },
+               newGame: function(mode, fenInit, color, oppId, continuation) {
+                       const fen = fenInit || VariantRules.GenRandInitFen();
+                       console.log(fen); //DEBUG
+                       if (mode=="human" && !oppId)
+                       {
+                               // Send game request and wait..
+                               this.clearStorage(); //in case of
+                               this.conn.send(JSON.stringify({code:"newgame", fen:fen}));
+                               document.getElementById("modal-control2").checked = true;
+                               return;
+                       }
+                       this.vr = new VariantRules(fen);
+                       this.mode = mode;
+                       if (mode=="human")
+                       {
+                               // Opponent found!
+                               if (!continuation)
+                               {
+                                       // Playing sound fails on game continuation:
+                                       new Audio("/sounds/newgame.mp3").play();
+                                       document.getElementById("modal-control2").checked = false;
+                               }
+                               this.oppid = oppId;
+                               this.oppConnected = true;
+                               this.mycolor = color;
+                       }
+                       else //against computer
+                       {
+                               this.mycolor = Math.random() < 0.5 ? 'w' : 'b';
+                               if (this.mycolor == 'b')
+                                       setTimeout(this.playComputerMove, 500);
+                       }
+               },
+               playComputerMove: function() {
+                       const compColor = this.mycolor=='w' ? 'b' : 'w';
+                       const compMove = this.vr.getComputerMove(compColor);
+                       // HACK: avoid selecting elements before they appear on page:
+                       setTimeout(() => this.play(compMove, "animate"), 500);
+               },
+               // Get the identifier of a HTML table cell from its numeric coordinates o.x,o.y.
+               getSquareId: function(o) {
+                       // NOTE: a separator is required to allow any size of board
+                       return  "sq-" + o.x + "-" + o.y;
+               },
+               // Inverse function
+               getSquareFromId: function(id) {
+                       let idParts = id.split('-');
+                       return [parseInt(idParts[1]), parseInt(idParts[2])];
+               },
+               mousedown: function(e) {
+                       e = e || window.event;
+                       e.preventDefault(); //disable native drag & drop
+                       if (!this.selectedPiece && e.target.classList.contains("piece"))
+                       {
+                               // Next few lines to center the piece on mouse cursor
+                               let rect = e.target.parentNode.getBoundingClientRect();
+                               this.start = {
+                                       x: rect.x + rect.width/2,
+                                       y: rect.y + rect.width/2,
+                                       id: e.target.parentNode.id
+                               };
+                               this.selectedPiece = e.target.cloneNode();
+                               this.selectedPiece.style.position = "absolute";
+                               this.selectedPiece.style.top = 0;
+                               this.selectedPiece.style.display = "inline-block";
+                               this.selectedPiece.style.zIndex = 3000;
+                               let startSquare = this.getSquareFromId(e.target.parentNode.id);
+                               this.possibleMoves = this.vr.canIplay(this.mycolor,startSquare)
+                                       ? this.vr.getPossibleMovesFrom(startSquare)
+                                       : [];
+                               e.target.parentNode.appendChild(this.selectedPiece);
+                       }
+               },
+               mousemove: function(e) {
+                       if (!this.selectedPiece)
+                               return;
+                       e = e || window.event;
+                       // If there is an active element, move it around
+                       if (!!this.selectedPiece)
+                       {
+                               this.selectedPiece.style.left = (e.clientX-this.start.x) + "px";
+                               this.selectedPiece.style.top = (e.clientY-this.start.y) + "px";
+                       }
+               },
+               mouseup: function(e) {
+                       if (!this.selectedPiece)
+                               return;
+                       e = e || window.event;
+                       // Read drop target (or parentElement, parentNode... if type == "img")
+                       this.selectedPiece.style.zIndex = -3000; //HACK to find square from final coordinates
+                       let landing = document.elementFromPoint(e.clientX, e.clientY);
+                       this.selectedPiece.style.zIndex = 3000;
+                       while (landing.tagName == "IMG") //classList.contains(piece) fails because of mark/highlight
+                               landing = landing.parentNode;
+                       if (this.start.id == landing.id) //a click: selectedPiece and possibleMoves already filled
+                               return;
+                       // OK: process move attempt
+                       let endSquare = this.getSquareFromId(landing.id);
+                       let moves = this.findMatchingMoves(endSquare);
+                       this.possibleMoves = [];
+                       if (moves.length > 1)
+                               this.choices = moves;
+                       else if (moves.length==1)
+                               this.play(moves[0]);
+                       // Else: impossible move
+                       this.selectedPiece.parentNode.removeChild(this.selectedPiece);
+                       delete this.selectedPiece;
+                       this.selectedPiece = null;
+               },
+               findMatchingMoves: function(endSquare) {
+                       // Run through moves list and return the matching set (if promotions...)
+                       let moves = [];
+                       this.possibleMoves.forEach(function(m) {
+                               if (endSquare[0] == m.end.x && endSquare[1] == m.end.y)
+                                       moves.push(m);
+                       });
+                       return moves;
+               },
+               animateMove: function(move) {
+                       let startSquare = document.getElementById(this.getSquareId(move.start));
+                       let endSquare = document.getElementById(this.getSquareId(move.end));
+                       let rectStart = startSquare.getBoundingClientRect();
+                       let rectEnd = endSquare.getBoundingClientRect();
+                       let translation = {x:rectEnd.x-rectStart.x, y:rectEnd.y-rectStart.y};
+                       let movingPiece = document.querySelector("#" + this.getSquareId(move.start) + " > img.piece");
+                       // HACK for animation (otherwise with positive translate, image slides "under background"...)
+                       // Possible improvement: just alter squares on the piece's way...
+                       squares = document.getElementsByClassName("board");
+                       for (let i=0; i<squares.length; i++)
+                       {
+                               let square = squares.item(i);
+                               if (square.id != this.getSquareId(move.start))
+                                       square.style.zIndex = "-1";
+                       }
+                       movingPiece.style.transform = "translate(" + translation.x + "px," + translation.y + "px)";
+                       movingPiece.style.transitionDuration = "0.2s";
+                       movingPiece.style.zIndex = "3000";
+                       setTimeout( () => {
+                               for (let i=0; i<squares.length; i++)
+                                       squares.item(i).style.zIndex = "auto";
+                               movingPiece.style = {}; //required e.g. for 0-0 with KR swap
+                               this.play(move);
+                       }, 200);
+               },
+               play: function(move, programmatic) {
+                       if (!!programmatic) //computer or human opponent
+                       {
+                               this.animateMove(move);
+                               return;
+                       }
+                       // Not programmatic, or animation is over
+                       if (this.mode == "human" && this.vr.turn == this.mycolor)
+                       {
+                               if (!this.oppConnected)
+                                       return; //abort move if opponent is gone
+                               this.conn.send(JSON.stringify({code:"newmove", move:move, oppid:this.oppid}));
+                       }
+                       new Audio("/sounds/chessmove1.mp3").play();
+                       this.vr.play(move, "ingame");
+                       if (this.mode == "human")
+                               this.updateStorage(); //after our moves and opponent moves
+                       const eog = this.vr.checkGameOver(this.vr.turn);
+                       if (eog != "*")
+                               this.endGame(eog);
+                       else if (this.mode == "computer" && this.vr.turn != this.mycolor)
+                               setTimeout(this.playComputerMove, 500);
+               },
+       },
+})
diff --git a/public/javascripts/components/rules.js b/public/javascripts/components/rules.js
new file mode 100644 (file)
index 0000000..e7af056
--- /dev/null
@@ -0,0 +1,71 @@
+Vue.component('my-rules', {
+       data: function() {
+               return { content: "" };
+       },
+       template: `<div v-html="content" class="section-content"></div>`,
+       mounted: function() {
+               // AJAX request to get rules content (plain text, HTML)
+               let xhr = new XMLHttpRequest();
+               let self = this;
+               xhr.onreadystatechange = function() {
+                       if (this.readyState == 4 && this.status == 200)
+                       {
+                               let replaceByDiag = (match, p1, p2) => { return self.drawDiag(p2); };
+                               self.content = xhr.responseText.replace(/(fen:)([^:]*):/g, replaceByDiag);
+                       }
+               };
+               xhr.open("GET", "/rules/" + variant, true);
+               xhr.setRequestHeader('X-Requested-With', "XMLHttpRequest");
+               xhr.send(null); //TODO: or just xhr.send() ?
+       },
+       methods: {
+               drawDiag: function(fen) {
+                       let [sizeX,sizeY] = VariantRules.size;
+                       let fenParts = fen.split(" ");
+                       // Obtain array of pieces images names
+                       let board = VariantRules.GetBoard(fenParts[0]);
+                       let orientation = "w";
+                       if (fenParts.length >= 2)
+                               orientation = fenParts[1];
+                       let markArray = [];
+                       if (fenParts.length >= 3)
+                       {
+                               let marks_str = fenParts[2];
+                               // Turn (human) marks into coordinates
+                               markArray = doubleArray(sizeX, sizeY, false);
+                               let marks = marks_str.split(",");
+                               for (let i=0; i<marks.length; i++)
+                               {
+                                       var res = /^([a-z]+)([0-9]+)$/i.exec(marks[i]);
+                                       let x = sizeX - parseInt(res[2]); //white at bottom, so counting is reversed
+                                       let y = res[1].charCodeAt(0)-97; //always one char: max 26, big enough
+                                       markArray[x][y] = true;
+                               }
+                       }
+                       let boardDiv = "";
+                       let [startX,startY,inc] = orientation == 'w'
+                               ? [0, 0, 1]
+                               : [sizeX-1, sizeY-1, -1];
+                       for (let i=startX; i>=0 && i<sizeX; i+=inc)
+                       {
+                               boardDiv += "<div class='row'>";
+                               for (let j=startY; j>=0 && j<sizeY; j+=inc)
+                               {
+                                       // NOTE: 'board' to distinguish from coords
+                                       boardDiv += "<div class='board lichess " +
+                                               ((i+j)%2==0 ? "light-square-diag" : "dark-square-diag") + "'>";
+                                       if (markArray.length>0 && markArray[i][j])
+                                               boardDiv += "<img src='/images/mark.svg' class='markSquare'/>";
+                                       if (board[i][j] != VariantRules.EMPTY)
+                                       {
+                                               boardDiv += "<img src='/images/pieces/" +
+                                                       VariantRules.getPpath(board[i][j]) + ".svg' class='piece'/>";
+                                       }
+                                       boardDiv += "</div>";
+                               }
+                               boardDiv += "</div>";
+                       }
+                       return boardDiv;
+               },
+       },
+})
diff --git a/public/javascripts/components/variantSummary.js b/public/javascripts/components/variantSummary.js
new file mode 100644 (file)
index 0000000..ed9b7b6
--- /dev/null
@@ -0,0 +1,23 @@
+Vue.component('my-variant-summary', {
+       props: ['vobj'],
+       template: `
+               <div class="variant col-sm-12" :id="vobj.name">
+                       <a :href="url">
+                               <h4 class="boxtitle text-center">
+                                       {{ vobj.name }}
+                                       <span class="count-players">
+                                               / {{ vobj.count }}
+                                       </span>
+                               </h4>
+                               <p class="description text-center">
+                                       {{ vobj.desc }}
+                               </p>
+                       </a>
+               </div>
+       `,
+       computed: {
+               url: function() {
+                       return "/" + this.vobj.name;
+               },
+       },
+})
diff --git a/public/javascripts/index.js b/public/javascripts/index.js
new file mode 100644 (file)
index 0000000..a05ad47
--- /dev/null
@@ -0,0 +1,67 @@
+const url = socketUrl;
+// random enough (TODO: function)
+const sid = (Date.now().toString(36) + Math.random().toString(36).substr(2, 7)).toUpperCase();
+const conn = new WebSocket(url + "/?sid=" + sid + "&page=index");
+
+conn.onmessage = msg => {
+       const data = JSON.parse(msg.data);
+       if (data.code == "counts")
+               //V.counts = data.counts;
+               Vue.set(V, "counts", data.counts);
+       else if (data.code == "increase")
+               V.counts[data.vname]++;
+       else if (data.code == "decrease")
+               V.counts[data.vname]--;
+}
+
+let V = new Vue({
+       el: "#indexPage",
+       data: {
+               counts: {},
+               curPrefix: "",
+       },
+       computed: {
+               sortedCounts: function () {
+                       const variantsCounts = variantArray.map( v => {
+                               return {
+                                       name: v.name,
+                                       desc: v.description,
+                                       count: this.counts[v.name] || 0,
+                               };
+                       });
+                       return variantsCounts.sort((a,b) => {
+                               if (a.count != b.count)
+                                       return b.count - a.count;
+                               // Else, alphabetic ordering
+                               return a.name.localeCompare(b.name);
+                       });
+               },
+       },
+       mounted: function() {
+               // Handle key stroke
+               document.onkeydown = event => {
+                       // Is it Back or Esc? If yes, apply action on current word
+                       if (event.keyCode == 8) //Back
+                       {
+                               event.preventDefault();
+                               this.curPrefix = this.curPrefix.slice(0,-1);
+                       }
+                       else if (event.keyCode == 27) //Esc
+                       {
+                               event.preventDefault();
+                               this.curPrefix = "";
+                       }
+                       // Is it alphanumeric? If yes, stack it
+                       else if (_.range(48,58).includes(event.keyCode)
+                               || _.range(65,91).includes(event.keyCode)
+                               || _.range(97,123).includes(event.keyCode))
+                       {
+                               let newChar = String.fromCharCode(event.keyCode);
+                               this.curPrefix += this.curPrefix.length==0
+                                       ? newChar.toUpperCase()
+                                       : newChar.toLowerCase();
+                       }
+                       // ...ignore everything else
+               };
+       },
+});
diff --git a/public/javascripts/utils/array.js b/public/javascripts/utils/array.js
new file mode 100644 (file)
index 0000000..ab1ae10
--- /dev/null
@@ -0,0 +1,37 @@
+// Remove item in array (if present)
+var removeItem = function(array, rfun)
+{
+       let index = array.findIndex(rfun);
+       if (index >= 0)
+               array.splice(index, 1);
+}
+
+// Remove several item matching a condition
+var removeMultiple = function(array, rfun)
+{
+       // Reverse loop because of the splice below
+       for (let i=array.length-1; i>=0; i--)
+       {
+               if (rfun(array[i]))
+                       array.splice(i, 1);
+       }
+}
+
+// Double array intialization
+var doubleArray = function(size1, size2, initElem)
+{
+       return _.map(_.range(size1), () => {
+               return _.map(_.range(size2), () => {
+                       return initElem; //can be undefined
+               })
+       });
+}
+
+var copyDoubleArray = function(arr)
+{
+       return _.map(_.range(arr.length), (el1,i) => {
+               return _.map(_.range(arr[0].length), (el2,j) => {
+                       return arr[i][j];
+               })
+       });
+}
diff --git a/public/javascripts/utils/socket_url.js.dist b/public/javascripts/utils/socket_url.js.dist
new file mode 100644 (file)
index 0000000..c33fc59
--- /dev/null
@@ -0,0 +1,2 @@
+// URL of your socket server (rename into socket_url.js)
+const socketUrl = "ws://localhost:3000";
diff --git a/public/javascripts/variants/Atomic.js b/public/javascripts/variants/Atomic.js
new file mode 100644 (file)
index 0000000..b7c7504
--- /dev/null
@@ -0,0 +1,144 @@
+class AtomicRules extends ChessRules
+{
+       getPotentialMovesFrom([x,y], c, lastMove)
+       {
+               let moves = super.getPotentialMovesFrom([x,y], c, lastMove);
+
+               // Handle explosions
+               moves.forEach(m => {
+                       if (m.vanish.length > 1 && m.appear.length <= 1) //avoid castles
+                       {
+                               // Explosion! TODO: drop moves which explode our king here
+                               let steps = [ [-1,-1],[-1,0],[-1,1],[0,-1],[0,1],[1,-1],[1,0],[1,1] ];
+                               for (let step of steps)
+                               {
+                                       let x = m.end.x + step[0];
+                                       let y = m.end.y + step[1];
+                                       if (x>=0 && x<8 && y>=0 && y<8 && this.board[x][y] != VariantRules.EMPTY
+                                               && this.getPiece(x,y) != VariantRules.PAWN)
+                                       {
+                                               m.vanish.push(new PiPo({p:this.getPiece(x,y),c:this.getColor(x,y),x:x,y:y}));
+                                       }
+                               }
+                               m.end = {x:m.appear[0].x, y:m.appear[0].y};
+                               m.appear.pop(); //Nothin appears in this case
+                       }
+               });
+
+               return moves;
+       }
+
+       getPotentialKingMoves(x, y, c)
+       {
+               // King cannot capture:
+               let moves = [];
+               let [sizeX,sizeY] = VariantRules.size;
+               const steps = VariantRules.steps[VariantRules.QUEEN];
+               for (let step of steps)
+               {
+                       var i = x + step[0];
+                       var j = y + step[1];
+                       if (i>=0 && i<sizeX && j>=0 && j<sizeY && this.board[i][j] == VariantRules.EMPTY)
+                               moves.push(this.getBasicMove(x, y, i, j));
+               }
+               return moves.concat(this.getCastleMoves(x,y,c));
+       }
+
+       isAttacked(sq, color)
+       {
+               if (this.getPiece(sq[0],sq[1]) == VariantRules.KING && this.isAttackedByKing(sq, color))
+                       return false; //king cannot take...
+               return (this.isAttackedByPawn(sq, color)
+                       || this.isAttackedByRook(sq, color)
+                       || this.isAttackedByKnight(sq, color)
+                       || this.isAttackedByBishop(sq, color)
+                       || this.isAttackedByQueen(sq, color));
+       }
+
+       updateVariables(move)
+       {
+               super.updateVariables(move);
+
+               const c = this.getColor(move.start.x,move.start.y);
+               // Next condition to avoid conflicts with harmless castle moves
+               if (c != this.getColor(move.end.x,move.end.y)
+                       && this.board[move.end.x][move.end.y] != VariantRules.EMPTY)
+               {
+                       const oppCol = this.getOppCol(c);
+                       const oppFirstRank = (oppCol == "w" ? 7 : 0);
+
+                       // Did we explode our king ? (TODO: remove move earlier)
+                       if (Math.abs(this.kingPos[c][0]-move.end.x) <= 1
+                               && Math.abs(this.kingPos[c][1]-move.end.y) <= 1)
+                       {
+                               this.kingPos[c] = [-1,-1];
+                               this.flags[c] = [false,false];
+                       }
+
+                       // Did we explode opponent king ?
+                       if (Math.abs(this.kingPos[oppCol][0]-move.end.x) <= 1
+                               && Math.abs(this.kingPos[oppCol][1]-move.end.y) <= 1)
+                       {
+                               this.kingPos[oppCol] = [-1,-1];
+                               this.flags[oppCol] = [false,false];
+                       }
+                       else
+                       {
+                               // Now check if opponent init rook(s) exploded
+                               if (Math.abs(move.end.x-oppFirstRank) <= 1)
+                               {
+                                       if (Math.abs(move.end.y-this.INIT_COL_ROOK[oppCol][0]) <= 1)
+                                               this.flags[oppCol][0] = false;
+                                       if (Math.abs(move.end.y-this.INIT_COL_ROOK[oppCol][1]) <= 1)
+                                               this.flags[oppCol][1] = false;
+                               }
+                       }
+               }
+       }
+
+       undo(move)
+       {
+               super.undo(move);
+
+               const c = this.getColor(move.start.x,move.start.y);
+               const oppCol = this.getOppCol(c);
+               if ([this.kingPos[c][0],this.kingPos[oppCol][0]].some(e => { return e < 0; }))
+               {
+                       // There is a chance that last move blowed some king away..
+                       for (let psq of move.vanish)
+                       {
+                               if (psq.p == 'k')
+                                       this.kingPos[psq.c==c ? c : oppCol] = [psq.x, psq.y];
+                       }
+               }
+       }
+
+       underCheck(move, c)
+       {
+               const oppCol = this.getOppCol(c);
+               this.play(move);
+               let res = undefined;
+               // If our king disappeared, move is not valid
+               if (this.kingPos[c][0] < 0)
+                       res = true;
+               // If opponent king disappeared, move is valid
+               else if (this.kingPos[oppCol][0] < 0)
+                       res = false;
+               // Otherwise, if we remain under check, move is not valid
+               else
+                       res = this.isAttacked(this.kingPos[c], oppCol);
+               this.undo(move);
+               return res;
+       }
+
+       checkGameEnd(color)
+       {
+               const kp = this.kingPos[color];
+               if (kp[0] < 0) //king disappeared
+                       return color == "w" ? "0-1" : "1-0";
+               if (!this.isAttacked(kp, this.getOppCol(color)))
+                       return "1/2";
+               // Checkmate
+               return color == "w" ? "0-1" : "1-0";
+       }
+}
diff --git a/public/javascripts/variants/Checkered.js b/public/javascripts/variants/Checkered.js
new file mode 100644 (file)
index 0000000..322d8fc
--- /dev/null
@@ -0,0 +1,517 @@
+class CheckeredRules extends ChessRules
+{
+       // Path to pieces
+       static getPpath(b)
+       {
+               return b[0]=='c' ? "Checkered/"+b : b;
+       }
+       static board2fen(b)
+       {
+               const checkered_codes = {
+                       'p': 's',
+                       'q': 't',
+                       'r': 'u',
+                       'b': 'c',
+                       'n': 'o',
+               };
+               if (b[0]=="c")
+                       return checkered_codes[b[1]];
+               return ChessRules.board2fen(b);
+       }
+       static fen2board(f)
+       {
+               const checkered_pieces = {
+                       's': 'p',
+                       't': 'q',
+                       'u': 'r',
+                       'c': 'b',
+                       'o': 'n',
+               };
+               if (Object.keys(checkered_pieces).includes(f))
+                       return 'c'+checkered_pieces[f];
+               return ChessRules.fen2board(f);
+       }
+
+       initVariables(fen)
+       {
+               super.initVariables(fen);
+               // Decode last non-capturing checkered move (if any)
+               const cmove = fen.split(" ")[4];
+               if (cmove != "-")
+               {
+                       const piece = cmove.charAt(0);
+                       const startEnd = cmove.substr(1).split(";");
+                       const start = startEnd[0].split(",");
+                       const end = startEnd[1].split(",");
+                       this.moves.push(new Move({
+                               appear: [ new PiPo({c:"c", p:piece, x:end[0], y:end[1]}) ],
+                               vanish: [ new PiPo({c:"c", p:piece, x:start[0], y:start[1]}) ]
+                       }));
+               }
+       }
+
+       static GetFlags(fen)
+       {
+               let flags = [
+                       ChessRules.GetFlags(fen), //castle
+                       {
+                               "w": new Array(8), //pawns can move 2 squares
+                               "b": new Array(8)
+                       }
+               ];
+               const fenFlags = fen.split(" ")[1].substr(4); //skip first 4 digits, for castle
+               for (let c of ['w','b'])
+               {
+                       for (let i=0; i<8; i++)
+                               flags[1][c][i] = (fenFlags.charAt((c=='w'?0:8)+i) == '1');
+               }
+               return flags;
+       }
+
+       // can color1 take color2?
+       canTake(color1, color2)
+       {
+               // Checkered aren't captured
+               return color1 != color2 && color2 != 'c' && (color1 != 'c' || color2 != this.turn);
+       }
+
+       // Build regular move(s) from its initial and destination squares; tr: transformation
+       getBasicMove(sx, sy, ex, ey, tr)
+       {
+               if (this.board[ex][ey] == VariantRules.EMPTY)
+               {
+                       // No capture, standard move construction
+                       return [super.getBasicMove(sx,sy,ex,ey,tr)];
+               }
+               let moves = []; //captures: generally 2 choices, unless 'tr' is specified or piece==king
+               const startPiece = this.getPiece(sx,sy);
+               const endPiece = this.getPiece(ex,ey);
+               const startColor = this.getColor(sx,sy);
+               const endColor = this.getColor(ex,ey);
+               for (let piece of !!tr ? [tr] :
+                       (startPiece==VariantRules.KING ? VariantRules.KING : _.uniq([startPiece,endPiece])))
+               {
+                       var mv = new Move({
+                               appear: [
+                                       new PiPo({
+                                               x: ex,
+                                               y: ey,
+                                               c: startPiece==VariantRules.KING ? startColor : 'c',
+                                               p: piece
+                                       })
+                               ],
+                               vanish: [
+                                       new PiPo({
+                                               x: sx,
+                                               y: sy,
+                                               c: startColor,
+                                               p: startPiece
+                                       }),
+                                       new PiPo({
+                                               x: ex,
+                                               y: ey,
+                                               c: endColor,
+                                               p: endPiece
+                                       })
+                               ]
+                       });
+                       moves.push(mv);
+               }
+               return moves;
+       }
+
+       // Generic method to find possible moves of non-pawn pieces ("sliding or jumping")
+       getSlideNJumpMoves(x, y, color, steps, oneStep)
+       {
+               var moves = [];
+               let [sizeX,sizeY] = VariantRules.size;
+               outerLoop:
+               for (var loop=0; loop<steps.length; loop++)
+               {
+                       var step = steps[loop];
+                       var i = x + step[0];
+                       var j = y + step[1];
+                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
+                               && this.board[i][j] == VariantRules.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, i, j)[0]); //no capture
+                               if (oneStep !== undefined)
+                                       continue outerLoop;
+                               i += step[0];
+                               j += step[1];
+                       }
+                       if (i>=0 && i<8 && j>=0 && j<8 && this.canTake(color, this.getColor(i,j)))
+                               moves = moves.concat(this.getBasicMove(x, y, i, j));
+               }
+               return moves;
+       }
+
+       // What are the pawn moves from square x,y considering color "color" ?
+       getPotentialPawnMoves(x, y, color)
+       {
+               var moves = [];
+               var V = VariantRules;
+               let [sizeX,sizeY] = VariantRules.size;
+               const c = (color == 'c' ? this.turn : color);
+               const shift = (c == "w" ? -1 : 1);
+               let startRank = (c == "w" ? sizeY-2 : 1);
+               let lastRank = (c == "w" ? 0 : sizeY-1);
+
+               if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
+               {
+                       // Normal moves
+                       if (this.board[x+shift][y] == V.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, x+shift, y)[0]);
+                               if (x==startRank && this.board[x+2*shift][y] == V.EMPTY && this.flags[1][c][y])
+                               {
+                                       // Two squares jump
+                                       moves.push(this.getBasicMove(x, y, x+2*shift, y)[0]);
+                               }
+                       }
+                       // Captures
+                       if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1))
+                               && this.board[x+shift][y-1] != V.EMPTY)
+                       {
+                               moves = moves.concat(this.getBasicMove(x, y, x+shift, y-1));
+                       }
+                       if (y<sizeY-1 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y+1))
+                               && this.board[x+shift][y+1] != V.EMPTY)
+                       {
+                               moves = moves.concat(this.getBasicMove(x, y, x+shift, y+1));
+                       }
+               }
+
+               if (x+shift == lastRank)
+               {
+                       // Promotion
+                       let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+                       promotionPieces.forEach(p => {
+                               // Normal move
+                               if (this.board[x+shift][y] == V.EMPTY)
+                                       moves.push(this.getBasicMove(x, y, x+shift, y, p)[0]);
+                               // Captures
+                               if (y>0 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y-1))
+                                       && this.board[x+shift][y-1] != V.EMPTY)
+                               {
+                                       moves = moves.concat(this.getBasicMove(x, y, x+shift, y-1, p));
+                               }
+                               if (y<sizeY-1 && this.canTake(this.getColor(x,y), this.getColor(x+shift,y+1))
+                                       && this.board[x+shift][y+1] != V.EMPTY)
+                               {
+                                       moves = moves.concat(this.getBasicMove(x, y, x+shift, y+1, p));
+                               }
+                       });
+               }
+
+               // En passant
+               const Lep = this.epSquares.length;
+               const epSquare = Lep>0 ? this.epSquares[Lep-1] : undefined;
+               if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1)
+               {
+                       let epStep = epSquare.y - y;
+                       var enpassantMove = this.getBasicMove(x, y, x+shift, y+epStep)[0];
+                       enpassantMove.vanish.push({
+                               x: x,
+                               y: y+epStep,
+                               p: 'p',
+                               c: this.getColor(x,y+epStep)
+                       });
+                       enpassantMove.appear[0].c = 'c';
+                       moves.push(enpassantMove);
+               }
+
+               return moves;
+       }
+
+       getCastleMoves(x,y,c)
+       {
+               if (x != (c=="w" ? 7 : 0) || y != this.INIT_COL_KING[c])
+                       return []; //x isn't first rank, or king has moved (shortcut)
+
+               const V = VariantRules;
+
+               // Castling ?
+               const oppCol = this.getOppCol(c);
+               let moves = [];
+               let i = 0;
+               const finalSquares = [ [2,3], [6,5] ]; //king, then rook
+               castlingCheck:
+               for (let castleSide=0; castleSide < 2; castleSide++) //large, then small
+               {
+                       if (!this.flags[0][c][castleSide])
+                               continue;
+                       // If this code is reached, rooks and king are on initial position
+
+                       // Nothing on the path of the king (and no checks; OK also if y==finalSquare)?
+                       let step = finalSquares[castleSide][0] < y ? -1 : 1;
+                       for (i=y; i!=finalSquares[castleSide][0]; i+=step)
+                       {
+                               if (this.isAttacked([x,i], oppCol) || (this.board[x][i] != V.EMPTY &&
+                                       // NOTE: next check is enough, because of chessboard constraints
+                                       (this.getColor(x,i) != c || ![V.KING,V.ROOK].includes(this.getPiece(x,i)))))
+                               {
+                                       continue castlingCheck;
+                               }
+                       }
+
+                       // Nothing on the path to the rook?
+                       step = castleSide == 0 ? -1 : 1;
+                       for (i = y + step; i != this.INIT_COL_ROOK[c][castleSide]; i += step)
+                       {
+                               if (this.board[x][i] != V.EMPTY)
+                                       continue castlingCheck;
+                       }
+                       const rookPos = this.INIT_COL_ROOK[c][castleSide];
+
+                       // Nothing on final squares, except maybe king and castling rook?
+                       for (i=0; i<2; i++)
+                       {
+                               if (this.board[x][finalSquares[castleSide][i]] != V.EMPTY &&
+                                       this.getPiece(x,finalSquares[castleSide][i]) != V.KING &&
+                                       finalSquares[castleSide][i] != rookPos)
+                               {
+                                       continue castlingCheck;
+                               }
+                       }
+
+                       // If this code is reached, castle is valid
+                       moves.push( new Move({
+                               appear: [
+                                       new PiPo({x:x,y:finalSquares[castleSide][0],p:V.KING,c:c}),
+                                       new PiPo({x:x,y:finalSquares[castleSide][1],p:V.ROOK,c:c})],
+                               vanish: [
+                                       new PiPo({x:x,y:y,p:V.KING,c:c}),
+                                       new PiPo({x:x,y:rookPos,p:V.ROOK,c:c})],
+                               end: Math.abs(y - rookPos) <= 2
+                                       ? {x:x, y:rookPos}
+                                       : {x:x, y:y + 2 * (castleSide==0 ? -1 : 1)}
+                       }) );
+               }
+
+               return moves;
+       }
+
+       canIplay(color, sq)
+       {
+               return ((color=='w' && this.movesCount%2==0) || color=='c'
+                               || (color=='b' && this.movesCount%2==1))
+                       && [color,'c'].includes(this.getColor(sq[0], sq[1]));
+       }
+
+       // Does m2 un-do m1 ? (to disallow undoing checkered moves)
+       oppositeMoves(m1, m2)
+       {
+               return m1.appear.length == 1 && m2.appear.length == 1
+                       && m1.vanish.length == 1 && m2.vanish.length == 1
+//                     && _.isEqual(m1.appear[0], m2.vanish[0]) //fails in HH case
+//                     && _.isEqual(m1.vanish[0], m2.appear[0]);
+                       && m1.start.x == m2.end.x && m1.end.x == m2.start.x
+                       && m1.start.y == m2.end.y && m1.end.y == m2.start.y
+                       && m1.appear[0].c == m2.vanish[0].c && m1.appear[0].p == m2.vanish[0].p
+                       && m1.vanish[0].c == m2.appear[0].c && m1.vanish[0].p == m2.appear[0].p;
+       }
+
+       filterValid(moves)
+       {
+               if (moves.length == 0)
+                       return [];
+               let color = this.getColor( moves[0].start.x, moves[0].start.y );
+               return moves.filter(m => {
+                       const L = this.moves.length;
+                       if (L > 0 && this.oppositeMoves(this.moves[L-1], m))
+                               return false;
+                       return !this.underCheck(m, color);
+               });
+       }
+
+  isAttackedByPawn([x,y], c)
+  {
+               const color = (c=="c" ? this.turn : c);
+    let pawnShift = (color=="w" ? 1 : -1);
+    if (x+pawnShift>=0 && x+pawnShift<8)
+    {
+      for (let i of [-1,1])
+      {
+        if (y+i>=0 && y+i<8 && this.getPiece(x+pawnShift,y+i)==VariantRules.PAWN
+          && this.getColor(x+pawnShift,y+i)==c)
+        {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+       underCheck(move, c)
+       {
+               const color = c == 'c' ? this.turn : c;
+               this.play(move);
+               let res = this.isAttacked(this.kingPos[color], this.getOppCol(color))
+                       || this.isAttacked(this.kingPos[color], 'c'); //TODO: quite inefficient...
+               this.undo(move);
+               return res;
+       }
+
+       updateVariables(move)
+       {
+               const piece = this.getPiece(move.start.x,move.start.y);
+               const c = this.getColor(move.start.x,move.start.y);
+
+               if (c != 'c') //checkered not concerned by castle flags
+               {
+                       const firstRank = (c == "w" ? 7 : 0);
+                       // Update king position + flags
+                       if (piece == VariantRules.KING && move.appear.length > 0)
+                       {
+                               this.kingPos[c][0] = move.appear[0].x;
+                               this.kingPos[c][1] = move.appear[0].y;
+                               this.flags[0][c] = [false,false];
+                               return;
+                       }
+                       const oppCol = this.getOppCol(c);
+                       const oppFirstRank = 7 - firstRank;
+                       if (move.start.x == firstRank //our rook moves?
+                               && this.INIT_COL_ROOK[c].includes(move.start.y))
+                       {
+                               const flagIdx = move.start.y == this.INIT_COL_ROOK[c][0] ? 0 : 1;
+                               this.flags[0][c][flagIdx] = false;
+                       }
+                       else if (move.end.x == oppFirstRank //we took opponent rook?
+                               && this.INIT_COL_ROOK[c].includes(move.end.y))
+                       {
+                               const flagIdx = move.end.y == this.INIT_COL_ROOK[oppCol][0] ? 0 : 1;
+                               this.flags[0][oppCol][flagIdx] = false;
+                       }
+               }
+
+               // Does it turn off a 2-squares pawn flag?
+               const secondRank = [1,6];
+               if (secondRank.includes(move.start.x) && move.vanish[0].p == VariantRules.PAWN)
+                       this.flags[1][move.start.x==6 ? "w" : "b"][move.start.y] = false;
+       }
+
+       play(move, ingame)
+       {
+               super.play(move, ingame);
+               if (!ingame)
+                       this.moves.push(move); //needed for turn indication for checkered pieces
+       }
+
+       undo(move)
+       {
+               super.undo(move);
+               this.moves.pop();
+       }
+
+       checkGameEnd(color)
+       {
+               if (!this.isAttacked(this.kingPos[color], this.getOppCol(color))
+                       && !this.isAttacked(this.kingPos[color], 'c'))
+               {
+                       return "1/2";
+               }
+               // OK, checkmate
+               return color == "w" ? "0-1" : "1-0";
+       }
+
+       evalPosition()
+       {
+               const [sizeX,sizeY] = VariantRules.size;
+               let evaluation = 0;
+               //Just count material for now, considering checkered neutral (...)
+               for (let i=0; i<sizeX; i++)
+               {
+                       for (let j=0; j<sizeY; j++)
+                       {
+                               if (this.board[i][j] != VariantRules.EMPTY)
+                               {
+                                       const sqColor = this.getColor(i,j);
+                                       const sign = sqColor == "w" ? 1 : (sqColor=="b" ? -1 : 0);
+                                       evaluation += sign * VariantRules.VALUES[this.getPiece(i,j)];
+                               }
+                       }
+               }
+               return evaluation;
+       }
+
+       static GenRandInitFen()
+       {
+               let fen = ChessRules.GenRandInitFen();
+               return fen.replace(/ - 0$/, "1111111111111111 - 0 -");
+       }
+
+       getFen()
+       {
+               let fen = super.getFen() + " ";
+               const L = this.moves.length;
+               if (L > 0 && this.moves[L-1].vanish.length==1 && this.moves[L-1].appear[0].c=="c")
+               {
+                       // Ok, un-cancellable checkered move
+                       fen += this.moves[L-1].appear[0].p
+                               + this.moves[L-1].start.x + "," + this.moves[L-1].start.y + ";"
+                               + this.moves[L-1].end.x + "," + this.moves[L-1].end.y;
+               }
+               else fen += "-";
+               return fen;
+       }
+
+       getFlagsFen()
+       {
+               let fen = "";
+               // Add castling flags
+               for (let c of ['w','b'])
+               {
+                       for (let i=0; i<2; i++)
+                               fen += this.flags[0][c][i] ? '1' : '0';
+               }
+               // Add pawns flags
+               for (let c of ['w','b'])
+               {
+                       for (let i=0; i<8; i++)
+                               fen += this.flags[1][c][i] ? '1' : '0';
+               }
+               return fen;
+       }
+
+       getNotation(move)
+       {
+               if (move.appear.length == 2)
+               {
+                       // Castle
+                       if (move.end.y < move.start.y)
+                               return "0-0-0";
+                       else
+                               return "0-0";
+               }
+
+               // Translate final square
+               let finalSquare =
+                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+
+               let piece = this.getPiece(move.start.x, move.start.y);
+               if (piece == VariantRules.PAWN)
+               {
+                       // Pawn move
+                       let notation = "";
+                       if (move.vanish.length > 1)
+                       {
+                               // Capture
+                               let startColumn = String.fromCharCode(97 + move.start.y);
+                               notation = startColumn + "x" + finalSquare + "=" + move.appear[0].p.toUpperCase();
+                       }
+                       else //no capture
+                               notation = finalSquare;
+                       if (move.appear.length > 0 && piece != move.appear[0].p) //promotion
+                               notation += "=" + move.appear[0].p.toUpperCase();
+                       return notation;
+               }
+
+               else
+               {
+                       // Piece movement
+                       return piece.toUpperCase() + (move.vanish.length > 1 ? "x" : "") + finalSquare
+                               + (move.vanish.length > 1 ? "=" + move.appear[0].p.toUpperCase() : "");
+               }
+       }
+}
diff --git a/public/javascripts/variants/Chess960.js b/public/javascripts/variants/Chess960.js
new file mode 100644 (file)
index 0000000..1c8292c
--- /dev/null
@@ -0,0 +1,4 @@
+class Chess960Rules extends ChessRules
+{
+       // Standard rules
+}
diff --git a/public/javascripts/variants/Zen.js b/public/javascripts/variants/Zen.js
new file mode 100644 (file)
index 0000000..54c77ad
--- /dev/null
@@ -0,0 +1,263 @@
+class ZenRules extends ChessRules
+{
+       // TODO: some duplicated code in 2 next functions
+       getSlideNJumpMoves(x, y, color, steps, oneStep)
+       {
+               var moves = [];
+               let [sizeX,sizeY] = VariantRules.size;
+               outerLoop:
+               for (var loop=0; loop<steps.length; loop++)
+               {
+                       var step = steps[loop];
+                       var i = x + step[0];
+                       var j = y + step[1];
+                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
+                               && this.board[i][j] == VariantRules.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, i, j));
+                               if (oneStep !== undefined)
+                                       continue outerLoop;
+                               i += step[0];
+                               j += step[1];
+                       }
+                       // No capture check: handled elsewhere (next method)
+               }
+               return moves;
+       }
+
+       // follow steps from x,y until something is met.
+       // if met piece is opponent and same movement (asA): eat it!
+       findCaptures_aux(x, y, color, asA)
+       {
+               var moves = [];
+               var V = VariantRules;
+               var steps = asA != V.PAWN
+                       ? V.steps[asA]
+                       : color=='w' ? [[-1,-1],[-1,1]] : [[1,-1],[1,1]];
+               var oneStep = (asA==V.KNIGHT || asA==V.PAWN); //we don't capture king
+               let [sizeX,sizeY] = V.size;
+               let lastRank = (color == 'w' ? 0 : sizeY-1);
+               let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+               outerLoop:
+               for (var loop=0; loop<steps.length; loop++)
+               {
+                       var step = steps[loop];
+                       var i = x + step[0];
+                       var j = y + step[1];
+                       while (i>=0 && i<sizeX && j>=0 && j<sizeY
+                               && this.board[i][j] == V.EMPTY)
+                       {
+                               if (oneStep)
+                                       continue outerLoop;
+                               i += step[0];
+                               j += step[1];
+                       }
+                       if (i>=0 && i<sizeX && j>=0 && j<sizeY &&
+                               this.getColor(i,j) == this.getOppCol(color) && this.getPiece(i,j) == asA)
+                       {
+                               // eat!
+                               if (this.getPiece(x,y) == V.PAWN && i == lastRank)
+                               {
+                                       // Special case of promotion:
+                                       promotionPieces.forEach(p => {
+                                               moves.push(this.getBasicMove(x, y, i, j, p));
+                                       });
+                               }
+                               else
+                               {
+                                       // All other cases
+                                       moves.push(this.getBasicMove(x, y, i, j));
+                               }
+                       }
+               }
+               return moves;
+       }
+
+       // Find possible captures from a square: look in every direction!
+       findCaptures(x, y, color)
+       {
+               var moves = [];
+
+               // PAWN
+               Array.prototype.push.apply(moves,
+                       this.findCaptures_aux(x, y, color, VariantRules.PAWN));
+
+               // ROOK
+               Array.prototype.push.apply(moves,
+                       this.findCaptures_aux(x, y, color, VariantRules.ROOK));
+
+               // KNIGHT
+               Array.prototype.push.apply(moves,
+                       this.findCaptures_aux(x, y, color, VariantRules.KNIGHT));
+
+               // BISHOP
+               Array.prototype.push.apply(moves,
+                       this.findCaptures_aux(x, y, color, VariantRules.BISHOP));
+
+               // QUEEN
+               Array.prototype.push.apply(moves,
+                       this.findCaptures_aux(x, y, color, VariantRules.QUEEN));
+
+               return moves;
+       }
+
+       getPotentialPawnMoves(x, y, color)
+       {
+               var moves = [];
+               var V = VariantRules;
+               let [sizeX,sizeY] = VariantRules.size;
+               let shift = (color == 'w' ? -1 : 1);
+               let startRank = (color == 'w' ? sizeY-2 : 1);
+               let lastRank = (color == "w" ? 0 : sizeY-1);
+
+               if (x+shift >= 0 && x+shift < sizeX && x+shift != lastRank)
+               {
+                       // Normal moves
+                       if (this.board[x+shift][y] == V.EMPTY)
+                       {
+                               moves.push(this.getBasicMove(x, y, x+shift, y));
+                               if (x==startRank && this.board[x+2*shift][y] == V.EMPTY)
+                               {
+                                       //two squares jump
+                                       moves.push(this.getBasicMove(x, y, x+2*shift, y));
+                               }
+                       }
+               }
+
+               if (x+shift == lastRank)
+               {
+                       // Promotion
+                       let promotionPieces = [V.ROOK,V.KNIGHT,V.BISHOP,V.QUEEN];
+                       promotionPieces.forEach(p => {
+                               // Normal move
+                               if (this.board[x+shift][y] == V.EMPTY)
+                                       moves.push(this.getBasicMove(x, y, x+shift, y, p));
+                       });
+               }
+
+               // En passant
+               const Lep = this.epSquares.length;
+               const epSquare = Lep>0 ? this.epSquares[Lep-1] : undefined;
+               if (!!epSquare && epSquare.x == x+shift && Math.abs(epSquare.y - y) == 1)
+               {
+                       let epStep = epSquare.y - y;
+                       var enpassantMove = this.getBasicMove(x, y, x+shift, y+epStep);
+                       enpassantMove.vanish.push({
+                               x: x,
+                               y: y+epStep,
+                               p: 'p',
+                               c: this.getColor(x,y+epStep)
+                       });
+                       moves.push(enpassantMove);
+               }
+
+               // Add "zen" captures
+               Array.prototype.push.apply(moves, this.findCaptures(x, y, color));
+
+               return moves;
+       }
+
+       getPotentialRookMoves(x, y, color)
+       {
+               let noCaptures = this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.ROOK]);
+               let captures = this.findCaptures(x, y, color);
+               return noCaptures.concat(captures);
+       }
+
+       getPotentialKnightMoves(x, y, color)
+       {
+               let noCaptures = this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.KNIGHT], "oneStep");
+               let captures = this.findCaptures(x, y, color);
+               return noCaptures.concat(captures);
+       }
+
+       getPotentialBishopMoves(x, y, color)
+       {
+               let noCaptures = this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.BISHOP]);
+               let captures = this.findCaptures(x, y, color);
+               return noCaptures.concat(captures);
+       }
+
+       getPotentialQueenMoves(x, y, color)
+       {
+               let noCaptures = this.getSlideNJumpMoves(
+                       x, y, color, VariantRules.steps[VariantRules.QUEEN]);
+               let captures = this.findCaptures(x, y, color);
+               return noCaptures.concat(captures);
+       }
+
+       getPotentialKingMoves(x, y, c)
+       {
+               // Initialize with normal moves
+               let noCaptures = this.getSlideNJumpMoves(
+                       x, y, c, VariantRules.steps[VariantRules.QUEEN], "oneStep");
+               let captures = this.findCaptures(x, y, c);
+
+               let moves = noCaptures
+                       .concat(captures)
+                       .concat(this.getCastleMoves(x, y, c));
+
+               return moves;
+       }
+
+       getNotation(move)
+       {
+               // Recognize special moves first
+               if (move.appear.length == 2)
+               {
+                       // castle
+                       if (move.end.y < move.start.y)
+                               return "0-0-0";
+                       else
+                               return "0-0";
+               }
+
+               // Translate initial square (because pieces may fly unusually in this variant!)
+               let initialSquare =
+                       String.fromCharCode(97 + move.start.y) + (VariantRules.size[0]-move.start.x);
+
+               // Translate final square
+               let finalSquare =
+                       String.fromCharCode(97 + move.end.y) + (VariantRules.size[0]-move.end.x);
+
+               let notation = "";
+               let piece = this.rules.getPiece(move.start.x, move.start.y);
+               if (piece == VariantRules.PAWN)
+               {
+                       // pawn move (TODO: enPassant indication)
+                       if (move.vanish.length > 1)
+                       {
+                               // capture
+                               notation = initialSquare + "x" + finalSquare;
+                       }
+                       else //no capture
+                               notation = finalSquare;
+                       if (piece != move.appear[0].p) //promotion
+                               notation += "=" + move.appear[0].p.toUpperCase();
+               }
+
+               else
+               {
+                       // Piece movement
+                       notation = piece.toUpperCase();
+                       if (move.vanish.length > 1)
+                               notation += initialSquare + "x";
+                       notation += finalSquare;
+               }
+               return notation;
+       }
+
+       static get VALUES() { //TODO: experimental
+               return {
+                       'p': 1,
+                       'r': 3,
+                       'n': 2,
+                       'b': 2,
+                       'q': 5,
+                       'k': 1000
+               }
+       }
+}
diff --git a/public/sounds/SOURCE b/public/sounds/SOURCE
new file mode 100644 (file)
index 0000000..545cb0a
--- /dev/null
@@ -0,0 +1,3 @@
+https://www.youtube.com/watch?v=LfbJs4uoHF0
+https://audiojungle.net/item/chess-pieces-and-board/11657386
+http://freesound.org/search/?q=cancel + sword
diff --git a/public/sounds/chessmove1.mp3 b/public/sounds/chessmove1.mp3
new file mode 100644 (file)
index 0000000..8586f77
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat d9100d524f9bca2f601823d2422bd3c21ed1329c                18889
diff --git a/public/sounds/newgame.mp3 b/public/sounds/newgame.mp3
new file mode 100644 (file)
index 0000000..09dac63
--- /dev/null
@@ -0,0 +1 @@
+#$# git-fat fca619a21ac9647e2cf6888ecc78e84a3ca8011c                14194
diff --git a/public/stylesheets/index.sass b/public/stylesheets/index.sass
new file mode 100644 (file)
index 0000000..5d2033f
--- /dev/null
@@ -0,0 +1,8 @@
+.boxtitle
+  font-weight: bold
+
+.variant
+  color: black
+  margin-top: 20px
+  a
+    color: #663300
diff --git a/public/stylesheets/layout.sass b/public/stylesheets/layout.sass
new file mode 100644 (file)
index 0000000..8a26260
--- /dev/null
@@ -0,0 +1,15 @@
+html, *
+  font-size: 18px
+  font-family: "Open Sans", Arial, sans-serif
+
+body
+  padding: 1%
+
+a
+  color: #00B7FF
+
+.text-center
+  text-align: center
+
+.smallpad
+  padding: 5px
diff --git a/public/stylesheets/variant.sass b/public/stylesheets/variant.sass
new file mode 100644 (file)
index 0000000..5148410
--- /dev/null
@@ -0,0 +1,140 @@
+.container#variantPage
+  padding: 0
+
+// https://stackoverflow.com/questions/5445491/height-equal-to-dynamic-width-css-fluid-layout
+figure.diagram-container > .diagram
+  display: block
+  width: 45%
+  min-width: 300px
+  max-width: 800px
+  margin-left: auto
+  margin-right: auto
+
+.connected, .disconnected
+  width: 20px
+  height: 20px
+  margin: 0 auto 15px auto
+  border: 1px solid brown
+
+.connected
+  background-color: green
+
+.disconnected
+  background-color: red
+
+// TODO: div.board, board9, board10, board11, board12
+div.board
+  float: left
+  width: 12.5%
+  height: 0
+  padding-bottom: 12.5%
+  display: inline-block
+  position: relative
+
+#choices
+       margin-bottom: 10px
+
+#choices
+       margin: 0 auto 0 auto
+       position: relative
+       z-index: 300
+       overflow-y: inherit
+       background-color: rgba(0,0,0,0) //transparent
+
+#choices img
+       cursor: pointer
+       background-color: #e6ee9c
+
+#choices img:hover
+       background-color: skyblue
+
+img.choice-piece
+       height: 0
+       width: 90%
+       padding: 5%
+       height: 90%
+
+img.piece, img.mark-square, img.choice-piece
+       max-width: 100%
+       height: auto
+       display: block
+
+img.mark-square
+       opacity: 0.6
+
+img.ghost
+       position: absolute
+       opacity: 0.4
+       top: 0
+
+img.piece
+  width: 100%
+
+img.mark-square
+  width: 76%
+  position: absolute
+  top: 12%
+  left: 12%
+  opacity: .7
+
+figure.diagram-container > figcaption
+  display: block
+  clear: both
+  padding-top: 5px
+
+.light-square
+  background-color: #f0d9b5
+.dark-square
+  background-color: #b58863
+
+.highlight
+  background-color: #00cc00
+
+.light-square-diag
+  background-color: #e5e5ca
+.dark-square-diag
+  background-color: #6f8f57
+
+p.boxed
+  background-color: #FFCC66
+  padding: 5px
+
+.stageDelimiter
+  color: purple
+
+// To show (new) pieces, and/or there values...
+figure.showPieces > img
+  width: 50px
+
+figure.showPieces > figcaption
+  color: #6C6C6C
+
+figure.diagram-container
+  margin: 15px 0 15px 0
+  text-align: center
+  width: 100%
+  display: block
+
+.section-title
+  padding: 0
+
+.section-title > h4
+  padding: 5px
+
+.section-content
+  padding: 5px
+
+ol, ul:not(.browser-default)
+  padding-left: 20px
+
+ul:not(.browser-default)
+  margin-top: 5px
+
+ul:not(.browser-default) > li
+  list-style-type: disc
+
+.rulesTitle
+  font-weight: bold
+  cursor: pointer
+  padding: 3px;
+  background-color: lightgrey
diff --git a/routes/all.js b/routes/all.js
new file mode 100644 (file)
index 0000000..819b1e2
--- /dev/null
@@ -0,0 +1,28 @@
+var express = require('express');
+var router = express.Router();
+
+const Variants = require("../variants");
+
+// Home
+router.get('/', function(req, res, next) {
+  res.render('index', {
+               title: 'Express',
+               variantArray: Variants, //JSON.stringify(Variants)
+       });
+});
+
+// Variant
+router.get("/:vname([a-zA-Z0-9]+)", (req,res) => {
+       const vname = req.params["vname"];
+       res.render('variant', {
+               title: vname + ' Variant',
+               variant: vname,
+       });
+});
+
+// Load a rules page (AJAX)
+router.get("/rules/:variant([a-zA-Z0-9]+)", (req,res) => {
+  res.render("rules/" + req.params["variant"]);
+});
+
+module.exports = router;
diff --git a/sockets.js b/sockets.js
new file mode 100644 (file)
index 0000000..2a43e32
--- /dev/null
@@ -0,0 +1,94 @@
+//const url = require('url');
+const Variants = require("./variants");
+
+function getJsonFromUrl(url) {
+       var query = url.substr(2); //starts with "/?"
+       var result = {};
+       query.split("&").forEach(function(part) {
+               var item = part.split("=");
+               result[item[0]] = decodeURIComponent(item[1]);
+       });
+       return result;
+}
+
+module.exports = function(wss) {
+
+       let clients = { "index": {} };
+       let games = {}; //pending games (player sid)
+       for (const v of Variants)
+               clients[v.name] = {};
+
+       wss.on("connection", (socket, req) => {
+               //const params = new URL("http://localhost" + req.url).searchParams;
+               var query = getJsonFromUrl(req.url);
+               const sid = query["sid"]; //params.get("sid");
+               const page = query["page"]; //params.get("page");
+               clients[page][sid] = socket;
+               if (page == "index")
+               {
+                       // Send counting info
+                       const countings = {};
+                       for (const v of Variants)
+                               countings[v.name] = Object.keys(clients[v.name]).length;
+                       socket.send(JSON.stringify({code:"counts",counts:countings}));
+               }
+               else
+               {
+                       // Send to every client connected on index an update message for counts
+                       Object.keys(clients["index"]).forEach( k => {
+                               clients["index"][k].send(JSON.stringify({code:"increase",vname:page}));
+                       });
+                       // Also notify potential opponents: hit all clients which check if sid corresponds
+                       Object.keys(clients[page]).forEach( k => {
+                               clients[page][k].send(JSON.stringify({code:"connect",id:sid}));
+                       });
+                       socket.on("message", objtxt => {
+                               let obj = JSON.parse(objtxt);
+                               switch (obj.code)
+                               {
+                                       case "newmove":
+                                               clients[page][obj.oppid].send(JSON.stringify({code:"newmove",move:obj.move}));
+                                               break;
+                                       case "ping":
+                                               if (!!clients[page][obj.oppid])
+                                                       socket.send(JSON.stringify({code:"pong"}));
+                                               break;
+                                       case "newgame":
+                                               if (!!games[page])
+                                               {
+                                                       // Start a new game
+                                                       const oppId = games[page]["id"];
+                                                       const fen = games[page]["fen"];
+                                                       delete games[page];
+                                                       const mycolor = Math.random() < 0.5 ? 'w' : 'b';
+                                                       socket.send(JSON.stringify({code:"newgame",fen:fen,oppid:oppId,color:mycolor}));
+                                                       clients[page][oppId].send(JSON.stringify({code:"newgame",fen:fen,oppid:sid,color:mycolor=="w"?"b":"w"}));
+                                               }
+                                               else
+                                                       games[page] = {id:sid, fen:obj.fen}; //wait for opponent
+                                               break;
+                                       case "resign":
+                                               clients[page][obj.oppid].send(JSON.stringify({code:"resign"}));
+                                               break;
+                               }
+                       });
+               }
+               socket.on("close", () => {
+                       delete clients[page][sid];
+                       // Remove potential pending game
+                       if (!!games[page] && games[page]["id"] == sid)
+                               delete games[page];
+                       if (page != "index")
+                       {
+                               // Send to every client connected on index an update message for counts
+                               Object.keys(clients["index"]).forEach( k => {
+                                       clients["index"][k].send(JSON.stringify({code:"decrease",vname:page}));
+                               });
+                       }
+                       // Also notify potential opponents: hit all clients which check if sid corresponds
+                       Object.keys(clients[page]).forEach( k => {
+                               clients[page][k].send(JSON.stringify({code:"disconnect",id:sid}));
+                       });
+               });
+       });
+}
diff --git a/variants.js b/variants.js
new file mode 100644 (file)
index 0000000..0bb5c9e
--- /dev/null
@@ -0,0 +1,19 @@
+module.exports = [
+       { "name" : "Checkered", "description" : "Shared pieces" },
+       { "name" : "Zen", "description" : "Reverse captures" },
+       { "name" : "Atomic", "description" : "Explosive captures" },
+       { "name" : "Chess960", "description" : "Standard rules" },
+//  { "name" : "AntiKing", "description" : "Keep anti-king in check" },
+//  { "name" : "Magnetic", "description" : "Laws of attraction" },
+//  { "name" : "Alice", "description" : "Both sides of the mirror" },
+//  { "name" : "Cylindric", "description" : "Sides comunicate" },
+//  { "name" : "Moscow", "description" : "Custom pieces setup" },
+//  { "name" : "Grand", "description" : "Big board" },
+//  { "name" : "Wildebeest", "description" : "Balanced sliders & leapers" },
+//  { "name" : "Loser", "description" : "Lose all pieces" },
+//  { "name" : "Shatranj", "description" : "Ancestral rules" },
+//  { "name" : "Switching", "description" : "Exchange pieces positions" },
+//  { "name" : "Absorption", "description" : "Capture enhance movements" },
+//  { "name" : "Dark", "description" : "In the fog" },
+//  { "name" : "Kriegspiel", "description" : "Blind war" },
+];
diff --git a/views/error.pug b/views/error.pug
new file mode 100644 (file)
index 0000000..51ec12c
--- /dev/null
@@ -0,0 +1,6 @@
+extends layout
+
+block content
+  h1= message
+  h2= error.status
+  pre #{error.stack}
diff --git a/views/index.pug b/views/index.pug
new file mode 100644 (file)
index 0000000..392e27a
--- /dev/null
@@ -0,0 +1,24 @@
+extends layout
+
+block css
+       link(rel="stylesheet", href="/stylesheets/index.css")
+
+block content
+       .container#indexPage
+               .row
+                       .col-sm-12
+                               h1.text-center Welcome to v[ariant] chess club !
+               .row
+                       my-variant-summary(
+                               v-for="(v,idx) in sortedCounts",
+                               v-show="v.name.startsWith(curPrefix)",
+                               v-bind:vobj="v",
+                               v-bind:key="v.name")
+
+block javascripts
+       script.
+               const variantArray = !{JSON.stringify(variantArray)};
+               //JSON.parse("!{variantArray}".replace(/\&quot;/g,'"'));
+       script(src="/javascripts/utils/socket_url.js")
+       script(src="/javascripts/components/variantSummary.js")
+       script(src="/javascripts/index.js")
diff --git a/views/layout.pug b/views/layout.pug
new file mode 100644 (file)
index 0000000..10b1ae9
--- /dev/null
@@ -0,0 +1,29 @@
+doctype html
+html(lang="fr")
+
+       head
+               meta(charset="UTF-8")
+               title vchess - #{title}
+               meta(name="viewport", content="width=device-width, initial-scale=1")
+               meta(name="msapplication-config", content="/images/favicon/browserconfig.xml")
+               meta(name="theme-color", content="#ffffff")
+               link(rel="stylesheet", href="//cdnjs.cloudflare.com/ajax/libs/mini.css/3.0.0/mini-default.min.css")
+               link(rel="stylesheet", href="//fonts.googleapis.com/css?family=Open+Sans:400,700")
+               link(rel="apple-touch-icon", sizes="180x180", href="/images/favicon/apple-touch-icon.png")
+               link(rel="icon", type="image/png", sizes="32x32", href="/images/favicon/favicon-32x32.png")
+               link(rel="icon", type="image/png", sizes="16x16", href="/images/favicon/favicon-16x16.png")
+               link(rel="manifest", href="/images/favicon/manifest.json")
+               link(rel="mask-icon", href="/images/favicon/safari-pinned-tab.svg", color="#5bbad5")
+               link(rel="shortcut icon", href="/images/favicon/favicon.ico")
+               link(rel="stylesheet", href="/stylesheets/layout.css")
+               block css
+
+       body
+
+               main
+                       block content
+
+               script(src="//cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore-min.js")
+               script(src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js")
+               //script(src="https://cdn.jsdelivr.net/npm/vue") //prod
+               block javascripts
diff --git a/views/rules/Atomic.pug b/views/rules/Atomic.pug
new file mode 100644 (file)
index 0000000..008a35c
--- /dev/null
@@ -0,0 +1,40 @@
+p.boxed
+       | All captures result in an "explosion" through which all surrounding white and black pieces other than pawns are removed from play.
+
+h3 Specifications
+
+ul
+       li Chessboard: standard.
+       li Material: standard.
+       li Non-capturing moves: standard.
+       li Special moves: standard.
+       li Captures: explosions; see below.
+       li End of game: king explodes, or standard; see below.
+
+h3 Basics
+
+p
+       | When a piece captures an opponent figure on some square S, all pieces sitting on a square reachable by a king move from S are removed.
+       | The pawns, however, remain: they have to be taken directly to disappear.
+
+figure.diagram-container
+       .diagram
+               | fen:r3kbnr/pp3ppp/3p4/4p3/8/8/PPPPPPPP/R1BQKBNR:
+       figcaption After the moves 1.Nc3 d6?? 2.Nd5 e5 3.Nxc7
+
+h3 End of the game
+
+p There are two ways to win, by decreasing strength order:
+ol
+       li Explode opponent king
+       li Checkmate opponent king
+
+p Explosions have priority: a checkmate followed by a king explosion loses.
+
+p Note: since suicide is forbidden, a king can touch the opponent king - and become immune to checks.
+
+h3 Credits
+
+p
+       | Many resources can be found on the web (this variation is played on lichess and FICS, among others).
+       | This game was played first in 1995 at the German Internet Chess Server (GICS) according to Wikipedia.
diff --git a/views/rules/Checkered.pug b/views/rules/Checkered.pug
new file mode 100644 (file)
index 0000000..600c3d5
--- /dev/null
@@ -0,0 +1,72 @@
+p.boxed
+       | The capture of an enemy piece produces a new "checkered" piece belonging to both players.
+
+figure.showPieces.center-align
+       img(src="/images/tmp_checkered/cp.png")
+       img(src="/images/tmp_checkered/cr.png")
+       img(src="/images/tmp_checkered/cn.png")
+       img(src="/images/tmp_checkered/cb.png")
+       img(src="/images/tmp_checkered/cq.png")
+       img(src="/images/tmp_checkered/no_ck.png")
+       figcaption Checkered pieces, born after captures.
+
+h3 Specifications
+
+ul
+       li Chessboard: standard.
+       li Material: additional checkered pieces.
+       li Non-capturing moves: standard; see below.
+       li Special moves: standard; see below.
+       li Captures: standard; see below.
+       li End of game: standard.
+
+p The game potentially evolves in two stages.
+
+h2.stageDelimiter Stage 1
+
+h3 Basics
+
+ol
+       li Each capture produces a new piece, taking on nature of the capturing or captured one.
+       li The new piece arising from a capture has a new color: "checkered", as illustrated above.
+       li All checkered pieces belong to the player in turn and can capture the opponents pieces.
+
+span Remarks:
+ul
+       li A checkered move cannot be "undone" right after if this repeat the position.
+       li Checkered chess pieces cannot be captured.
+
+figure.diagram-container
+       .diagram
+               | fen:2kr4/pp6/2p5/4ss1r/1P2ns1P/2Np4/P1P1P1BP/R2o1RK1:
+       figcaption.
+               Black plays Rxh4=P. (Checkered pawn to) h5 is allowed then, because piece's nature changed.
+
+h3 Pawn moves
+
+ul
+       li A pawn captured on its starting square keeps the right to advance two squares.
+       li Checkered pawns cannot capture en passant.
+
+h2.stageDelimiter Stage 2
+
+p.
+       During the game one of the two players can decide to take control of the checkered pieces.
+       They thus become autonomous and vulnerable to being captured - stage 2 begins.
+       The other player is in charge of both the white and black pieces, and tries to eliminate checkered pieces.
+       The checkered side wins by checkmating either the white or black king.
+
+h3 Special moves
+
+span Checkered pawns can...
+ul
+       li move and capture in either direction;
+       li take en passant,
+       li be promoted on either the first or eighth row.
+
+h3 Credits
+
+ul
+       li The rules of Checkered Chess were thought up by Patrick Bernier and developed with the help of Benjamin Auder.
+       li Thanks to Bevis Martin for the initial english translation.
+       li Thanks also to Christian Poisson, Laurent Nouhaud and Frédéric Fradet.
diff --git a/views/rules/Chess960.pug b/views/rules/Chess960.pug
new file mode 100644 (file)
index 0000000..8f70e45
--- /dev/null
@@ -0,0 +1,3 @@
+p.boxed
+       | Orthodox rules (still with shuffled starting position). See for example the 
+       a(href="https://en.wikipedia.org/wiki/Rules_of_chess") Wikipedia page.
diff --git a/views/rules/Zen.pug b/views/rules/Zen.pug
new file mode 100644 (file)
index 0000000..4114043
--- /dev/null
@@ -0,0 +1,41 @@
+p.boxed
+       | Zen chess only change one thing to the standard rules:
+       | a piece A captures an opponent piece B if and only if B can take A according to the orthodox rules.
+
+figure.diagram-container
+       .diagram
+               | fen:r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R:
+       figcaption After 3.Bb5?? black can play 3...Nxb5 or 3...e5xf3 for example
+
+h3 Specifications
+
+ul
+       li Chessboard: standard.
+       li Material: standard.
+       li Non-capturing moves: standard.
+       li Special moves: standard.
+       li Captures: reverse, as stated above.
+       li End of game: standard; see below.
+
+h3 End of the game
+
+p Conforming to the rule, the king captures the pieces which are attacking him.
+
+figure.diagram-container
+       .diagram
+               | fen:8/8/8/3r1k2/8/8/3K4/8:
+       figcaption The white king can take the rook
+
+p However, the king is attacked in the same way as in regular chess - and it's the only exception.
+
+figure.diagram-container
+       .diagram
+               | fen:r7/2n5/1q6/5k2/8/8/K7/8:
+       figcaption The king cannot take on a8 because it's guarded by the knight: it's checkmate
+
+h3 Credits
+
+p.
+       Very few resources about this variation: #[a(href="http://play.chessvariants.org/erf/ZenChess.html") this webpage] 
+       and #[a(href="http://www.pathguy.com/chess/ZenChess.htm") this one].
+       Ed Friedlander developed the Zen Chess applet from the link above.
diff --git a/views/variant.pug b/views/variant.pug
new file mode 100644 (file)
index 0000000..7f4d6ef
--- /dev/null
@@ -0,0 +1,30 @@
+extends layout
+
+block css
+       link(rel="stylesheet", href="//fonts.googleapis.com/icon?family=Material+Icons")
+       link(rel="stylesheet", href="/stylesheets/variant.css")
+
+block content
+       .container#variantPage
+               .row
+                       .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
+                               h4.rulesTitle.text-center(v-on:click="displayRules=!displayRules") #{variant} Rules
+                               my-rules(v-show="displayRules")
+                       .col-sm-12.col-md-10.col-md-offset-1.col-lg-8.col-lg-offset-2
+                               my-game
+
+block javascripts
+       script(src="/javascripts/utils/socket_url.js")
+       script(src="/javascripts/utils/array.js")
+       script(src="/javascripts/base_rules.js")
+       script(src="/javascripts/variants/" + variant + ".js")
+       script.
+               const VariantRules = #{variant}Rules;
+               const variant = "#{variant}";
+       script(src="/javascripts/components/rules.js")
+       script(src="/javascripts/components/game.js")
+       script.
+               new Vue({
+                       el: "#variantPage",
+                       data: { displayRules: false },
+               });