Demo for query storing

Change-Id: I947bcac841992c3f6cfd01ab337c265b0d01cb70
diff --git a/node_modules/tiny-lr/src/client.js b/node_modules/tiny-lr/src/client.js
new file mode 100644
index 0000000..9dab252
--- /dev/null
+++ b/node_modules/tiny-lr/src/client.js
@@ -0,0 +1,145 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _events = require('events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _fayeWebsocket = require('faye-websocket');
+
+var _fayeWebsocket2 = _interopRequireDefault(_fayeWebsocket);
+
+var _objectAssign = require('object-assign');
+
+var _objectAssign2 = _interopRequireDefault(_objectAssign);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var debug = require('debug')('tinylr:client');
+
+var idCounter = 0;
+
+var Client = function (_events$EventEmitter) {
+  _inherits(Client, _events$EventEmitter);
+
+  function Client(req, socket, head) {
+    var options = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
+
+    _classCallCheck(this, Client);
+
+    var _this = _possibleConstructorReturn(this, (Client.__proto__ || Object.getPrototypeOf(Client)).call(this));
+
+    _this.options = options;
+    _this.ws = new _fayeWebsocket2.default(req, socket, head);
+    _this.ws.onmessage = _this.message.bind(_this);
+    _this.ws.onclose = _this.close.bind(_this);
+    _this.id = _this.uniqueId('ws');
+    return _this;
+  }
+
+  _createClass(Client, [{
+    key: 'message',
+    value: function message(event) {
+      var data = this.data(event);
+      if (this[data.command]) return this[data.command](data);
+    }
+  }, {
+    key: 'close',
+    value: function close(event) {
+      if (this.ws) {
+        this.ws.close();
+        this.ws = null;
+      }
+
+      this.emit('end', event);
+    }
+
+    // Commands
+
+  }, {
+    key: 'hello',
+    value: function hello() {
+      this.send({
+        command: 'hello',
+        protocols: ['http://livereload.com/protocols/official-7'],
+        serverName: 'tiny-lr'
+      });
+    }
+  }, {
+    key: 'info',
+    value: function info(data) {
+      if (data) {
+        debug('Info', data);
+        this.emit('info', (0, _objectAssign2.default)({}, data, { id: this.id }));
+        this.plugins = data.plugins;
+        this.url = data.url;
+      }
+
+      return (0, _objectAssign2.default)({}, data || {}, { id: this.id, url: this.url });
+    }
+
+    // Server commands
+
+  }, {
+    key: 'reload',
+    value: function reload(files) {
+      files.forEach(function (file) {
+        this.send({
+          command: 'reload',
+          path: file,
+          liveCSS: this.options.liveCSS !== false,
+          reloadMissingCSS: this.options.reloadMissingCSS !== false,
+          liveImg: this.options.liveImg !== false
+        });
+      }, this);
+    }
+  }, {
+    key: 'alert',
+    value: function alert(message) {
+      this.send({
+        command: 'alert',
+        message: message
+      });
+    }
+
+    // Utilities
+
+  }, {
+    key: 'data',
+    value: function data(event) {
+      var data = {};
+      try {
+        data = JSON.parse(event.data);
+      } catch (e) {}
+      return data;
+    }
+  }, {
+    key: 'send',
+    value: function send(data) {
+      if (!this.ws) return;
+      this.ws.send(JSON.stringify(data));
+    }
+  }, {
+    key: 'uniqueId',
+    value: function uniqueId(prefix) {
+      var id = idCounter++;
+      return prefix ? prefix + id : id;
+    }
+  }]);
+
+  return Client;
+}(_events2.default.EventEmitter);
+
+exports.default = Client;
+module.exports = exports['default'];
\ No newline at end of file
diff --git a/node_modules/tiny-lr/src/index.js b/node_modules/tiny-lr/src/index.js
new file mode 100644
index 0000000..b2a36c4
--- /dev/null
+++ b/node_modules/tiny-lr/src/index.js
@@ -0,0 +1,61 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _server = require('./server');
+
+var _server2 = _interopRequireDefault(_server);
+
+var _client = require('./client');
+
+var _client2 = _interopRequireDefault(_client);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+var debug = require('debug')('tinylr');
+
+// Need to keep track of LR servers when notifying
+var servers = [];
+
+exports.default = tinylr;
+
+// Expose Server / Client objects
+
+tinylr.Server = _server2.default;
+tinylr.Client = _client2.default;
+
+// and the middleware helpers
+tinylr.middleware = middleware;
+tinylr.changed = changed;
+
+// Main entry point
+function tinylr(opts) {
+  var srv = new _server2.default(opts);
+  servers.push(srv);
+  return srv;
+}
+
+// A facade to Server#handle
+function middleware(opts) {
+  var srv = new _server2.default(opts);
+  servers.push(srv);
+  return function tinylr(req, res, next) {
+    srv.handler(req, res, next);
+  };
+}
+
+// Changed helper, helps with notifying the server of a file change
+function changed(done) {
+  var files = [].slice.call(arguments);
+  if (typeof files[files.length - 1] === 'function') done = files.pop();
+  done = typeof done === 'function' ? done : function () {};
+  debug('Notifying %d servers - Files: ', servers.length, files);
+  servers.forEach(function (srv) {
+    var params = { params: { files: files } };
+    srv && srv.changed(params);
+  });
+  done();
+}
+module.exports = exports['default'];
\ No newline at end of file
diff --git a/node_modules/tiny-lr/src/server.js b/node_modules/tiny-lr/src/server.js
new file mode 100644
index 0000000..c08adf6
--- /dev/null
+++ b/node_modules/tiny-lr/src/server.js
@@ -0,0 +1,396 @@
+'use strict';
+
+Object.defineProperty(exports, "__esModule", {
+  value: true
+});
+
+var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
+
+var _fs = require('fs');
+
+var _fs2 = _interopRequireDefault(_fs);
+
+var _http = require('http');
+
+var _http2 = _interopRequireDefault(_http);
+
+var _https = require('https');
+
+var _https2 = _interopRequireDefault(_https);
+
+var _events = require('events');
+
+var _events2 = _interopRequireDefault(_events);
+
+var _url = require('url');
+
+var _client = require('./client');
+
+var _client2 = _interopRequireDefault(_client);
+
+var _package = require('../package.json');
+
+var _package2 = _interopRequireDefault(_package);
+
+var _any = require('body/any');
+
+var _any2 = _interopRequireDefault(_any);
+
+var _qs = require('qs');
+
+var _qs2 = _interopRequireDefault(_qs);
+
+function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
+
+function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
+
+function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
+
+function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
+
+var debug = require('debug')('tinylr:server');
+
+var CONTENT_TYPE = 'content-type';
+var FORM_TYPE = 'application/x-www-form-urlencoded';
+
+function buildRootPath() {
+  var prefix = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/';
+
+  var rootUrl = prefix;
+
+  // Add trailing slash
+  if (prefix[prefix.length - 1] !== '/') {
+    rootUrl = rootUrl + '/';
+  }
+
+  // Add leading slash
+  if (prefix[0] !== '/') {
+    rootUrl = '/' + rootUrl;
+  }
+
+  return rootUrl;
+}
+
+var Server = function (_events$EventEmitter) {
+  _inherits(Server, _events$EventEmitter);
+
+  function Server() {
+    var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
+
+    _classCallCheck(this, Server);
+
+    var _this = _possibleConstructorReturn(this, (Server.__proto__ || Object.getPrototypeOf(Server)).call(this));
+
+    _this.options = options;
+
+    options.livereload = options.livereload || require.resolve('livereload-js/dist/livereload.js');
+
+    // todo: change falsy check to allow 0 for random port
+    options.port = parseInt(options.port || 35729, 10);
+
+    if (options.errorListener) {
+      _this.errorListener = options.errorListener;
+    }
+
+    _this.rootPath = buildRootPath(options.prefix);
+
+    _this.clients = {};
+    _this.configure(options.app);
+    _this.routes(options.app);
+    return _this;
+  }
+
+  _createClass(Server, [{
+    key: 'routes',
+    value: function routes() {
+      if (!this.options.dashboard) {
+        this.on('GET ' + this.rootPath, this.index.bind(this));
+      }
+
+      this.on('GET ' + this.rootPath + 'changed', this.changed.bind(this));
+      this.on('POST ' + this.rootPath + 'changed', this.changed.bind(this));
+      this.on('POST ' + this.rootPath + 'alert', this.alert.bind(this));
+      this.on('GET ' + this.rootPath + 'livereload.js', this.livereload.bind(this));
+      this.on('GET ' + this.rootPath + 'kill', this.close.bind(this));
+    }
+  }, {
+    key: 'configure',
+    value: function configure(app) {
+      var _this2 = this;
+
+      debug('Configuring %s', app ? 'connect / express application' : 'HTTP server');
+
+      var handler = this.options.handler || this.handler;
+
+      if (!app) {
+        if (this.options.key && this.options.cert || this.options.pfx) {
+          this.server = _https2.default.createServer(this.options, handler.bind(this));
+        } else {
+          this.server = _http2.default.createServer(handler.bind(this));
+        }
+
+        this.server.on('upgrade', this.websocketify.bind(this));
+        this.server.on('error', this.error.bind(this));
+        return this;
+      }
+
+      this.app = app;
+      this.app.listen = function (port, done) {
+        done = done || function () {};
+        if (port !== _this2.options.port) {
+          debug('Warn: LiveReload port is not standard (%d). You are listening on %d', _this2.options.port, port);
+          debug('You\'ll need to rely on the LiveReload snippet');
+          debug('> http://feedback.livereload.com/knowledgebase/articles/86180-how-do-i-add-the-script-tag-manually-');
+        }
+
+        var srv = _this2.server = _http2.default.createServer(app);
+        srv.on('upgrade', _this2.websocketify.bind(_this2));
+        srv.on('error', _this2.error.bind(_this2));
+        srv.on('close', _this2.close.bind(_this2));
+        return srv.listen(port, done);
+      };
+
+      return this;
+    }
+  }, {
+    key: 'handler',
+    value: function handler(req, res, next) {
+      var _this3 = this;
+
+      var middleware = typeof next === 'function';
+      debug('LiveReload handler %s (middleware: %s)', req.url, middleware ? 'on' : 'off');
+
+      next = next || this.defaultHandler.bind(this, res);
+      req.headers[CONTENT_TYPE] = req.headers[CONTENT_TYPE] || FORM_TYPE;
+      return (0, _any2.default)(req, res, function (err, body) {
+        if (err) return next(err);
+        req.body = body;
+
+        if (!req.query) {
+          req.query = req.url.indexOf('?') !== -1 ? _qs2.default.parse((0, _url.parse)(req.url).query) : {};
+        }
+
+        return _this3.handle(req, res, next);
+      });
+    }
+  }, {
+    key: 'index',
+    value: function index(req, res) {
+      res.setHeader('Content-Type', 'application/json');
+      res.write(JSON.stringify({
+        tinylr: 'Welcome',
+        version: _package2.default.version
+      }));
+
+      res.end();
+    }
+  }, {
+    key: 'handle',
+    value: function handle(req, res, next) {
+      var url = (0, _url.parse)(req.url);
+      debug('Request:', req.method, url.href);
+      var middleware = typeof next === 'function';
+
+      // do the routing
+      var route = req.method + ' ' + url.pathname;
+      var respond = this.emit(route, req, res);
+      if (respond) return;
+
+      if (middleware) return next();
+
+      // Only apply content-type on non middleware setup #70
+      return this.notFound(res);
+    }
+  }, {
+    key: 'defaultHandler',
+    value: function defaultHandler(res, err) {
+      if (!err) return this.notFound(res);
+
+      this.error(err);
+      res.setHeader('Content-Type', 'text/plain');
+      res.statusCode = 500;
+      res.end('Error: ' + err.stack);
+    }
+  }, {
+    key: 'notFound',
+    value: function notFound(res) {
+      res.setHeader('Content-Type', 'application/json');
+      res.writeHead(404);
+      res.write(JSON.stringify({
+        error: 'not_found',
+        reason: 'no such route'
+      }));
+      res.end();
+    }
+  }, {
+    key: 'websocketify',
+    value: function websocketify(req, socket, head) {
+      var _this4 = this;
+
+      var client = new _client2.default(req, socket, head, this.options);
+      this.clients[client.id] = client;
+
+      // handle socket error to prevent possible app crash, such as ECONNRESET
+      socket.on('error', function (e) {
+        // ignore frequent ECONNRESET error (seems inevitable when refresh)
+        if (e.code === 'ECONNRESET') return;
+        _this4.error(e);
+      });
+
+      client.once('info', function (data) {
+        debug('Create client %s (url: %s)', data.id, data.url);
+        _this4.emit('MSG /create', data.id, data.url);
+      });
+
+      client.once('end', function () {
+        debug('Destroy client %s (url: %s)', client.id, client.url);
+        _this4.emit('MSG /destroy', client.id, client.url);
+        delete _this4.clients[client.id];
+      });
+    }
+  }, {
+    key: 'listen',
+    value: function listen(port, host, fn) {
+      port = port || this.options.port;
+
+      // Last used port for error display
+      this.port = port;
+
+      if (typeof host === 'function') {
+        fn = host;
+        host = undefined;
+      }
+
+      this.server.listen(port, host, fn);
+    }
+  }, {
+    key: 'close',
+    value: function close(req, res) {
+      Object.keys(this.clients).forEach(function (id) {
+        this.clients[id].close();
+      }, this);
+
+      if (this.server._handle) this.server.close(this.emit.bind(this, 'close'));
+
+      if (res) res.end();
+    }
+  }, {
+    key: 'error',
+    value: function error(e) {
+      if (this.errorListener) {
+        this.errorListener(e);
+        return;
+      }
+
+      console.error();
+      if (typeof e === 'undefined') {
+        console.error('... Uhoh. Got error %s ...', e);
+      } else {
+        console.error('... Uhoh. Got error %s ...', e.message);
+        console.error(e.stack);
+
+        if (e.code !== 'EADDRINUSE') return;
+        console.error();
+        console.error('You already have a server listening on %s', this.port);
+        console.error('You should stop it and try again.');
+        console.error();
+      }
+    }
+
+    // Routes
+
+  }, {
+    key: 'livereload',
+    value: function livereload(req, res) {
+      res.setHeader('Content-Type', 'application/javascript');
+      _fs2.default.createReadStream(this.options.livereload).pipe(res);
+    }
+  }, {
+    key: 'changed',
+    value: function changed(req, res) {
+      var files = this.param('files', req);
+
+      debug('Changed event (Files: %s)', files.join(' '));
+      var clients = this.notifyClients(files);
+
+      if (!res) return;
+
+      res.setHeader('Content-Type', 'application/json');
+      res.write(JSON.stringify({
+        clients: clients,
+        files: files
+      }));
+
+      res.end();
+    }
+  }, {
+    key: 'alert',
+    value: function alert(req, res) {
+      var message = this.param('message', req);
+
+      debug('Alert event (Message: %s)', message);
+      var clients = this.alertClients(message);
+
+      if (!res) return;
+
+      res.setHeader('Content-Type', 'application/json');
+      res.write(JSON.stringify({
+        clients: clients,
+        message: message
+      }));
+
+      res.end();
+    }
+  }, {
+    key: 'notifyClients',
+    value: function notifyClients(files) {
+      var clients = Object.keys(this.clients).map(function (id) {
+        var client = this.clients[id];
+        debug('Reloading client %s (url: %s)', client.id, client.url);
+        client.reload(files);
+        return {
+          id: client.id,
+          url: client.url
+        };
+      }, this);
+
+      return clients;
+    }
+  }, {
+    key: 'alertClients',
+    value: function alertClients(message) {
+      var clients = Object.keys(this.clients).map(function (id) {
+        var client = this.clients[id];
+        debug('Alert client %s (url: %s)', client.id, client.url);
+        client.alert(message);
+        return {
+          id: client.id,
+          url: client.url
+        };
+      }, this);
+
+      return clients;
+    }
+
+    // Lookup param from body / params / query.
+
+  }, {
+    key: 'param',
+    value: function param(name, req) {
+      var param = void 0;
+      if (req.body && req.body[name]) param = req.body[name];else if (req.params && req.params[name]) param = req.params[name];else if (req.query && req.query[name]) param = req.query[name];
+
+      // normalize files array
+      if (name === 'files') {
+        param = Array.isArray(param) ? param : typeof param === 'string' ? param.split(/[\s,]/) : [];
+      }
+
+      return param;
+    }
+  }]);
+
+  return Server;
+}(_events2.default.EventEmitter);
+
+exports.default = Server;
+module.exports = exports['default'];
\ No newline at end of file