<commit_before>(function(global) {
  var RS = RemoteStorage;

  /**
   * Class: RemoteStorage.WireClient
   *
   * WireClient Interface
   * --------------------
   *
   * This file exposes a get/put/delete interface on top of XMLHttpRequest.
   * It requires to be configured with parameters about the remotestorage server to
   * connect to.
   * Each instance of WireClient is always associated with a single remotestorage
   * server and access token.
   *
   * Usually the WireClient instance can be accessed via `remoteStorage.remote`.
   *
   * This is the get/put/delete interface:
   *
   *   - #get() takes a path and optionally a ifNoneMatch option carrying a version
   *     string to check. It returns a promise that will be fulfilled with the HTTP
   *     response status, the response body, the MIME type as returned in the
   *     'Content-Type' header and the current revision, as returned in the 'ETag'
   *     header.
   *   - #put() takes a path, the request body and a content type string. It also
   *     accepts the ifMatch and ifNoneMatch options, that map to the If-Match and
   *     If-None-Match headers respectively. See the remotestorage-01 specification
   *     for details on handling these headers. It returns a promise, fulfilled with
   *     the same values as the one for #get().
   *   - #delete() takes a path and the ifMatch option as well. It returns a promise
   *     fulfilled with the same values as the one for #get().
   *
   * In addition to this, the WireClient has some compatibility features to work with
   * remotestorage 2012.04 compatible storages. For example it will cache revisions
   * from directory listings in-memory and return them accordingly as the "revision"
   * parameter in response to #get() requests. Similarly it will return 404 when it
   * receives an empty directory listing, to mimic remotestorage-01 behavior. Note
   * that it is not always possible to know the revision beforehand, hence it may
   * be undefined at times (especially for caching-roots).
   */

  var haveLocalStorage;
  var SETTINGS_KEY = "remotestorage:wireclient";

  var API_2012 = 1, API_00 = 2, API_01 = 3, API_HEAD = 4;

  var STORAGE_APIS = {
    'draft-dejong-remotestorage-00': API_00,
    'draft-dejong-remotestorage-01': API_01,
    'https://www.w3.org/community/rww/wiki/read-write-web-00#simple': API_2012
  };

  var isArrayBufferView;

  if (typeof(ArrayBufferView) === 'function') {
    isArrayBufferView = function(object) { return object && (object instanceof ArrayBufferView); };
  } else {
    var arrayBufferViews = [
      Int8Array, Uint8Array, Int16Array, Uint16Array,
      Int32Array, Uint32Array, Float32Array, Float64Array
    ];
    isArrayBufferView = function(object) {
      for(var i=0;i<8;i++) {
        if (object instanceof arrayBufferViews[i]) {
          return true;
        }
      }
      return false;
    };
  }

  function request(method, uri, token, headers, body, getEtag, fakeRevision) {
    if ((method === 'PUT' || method === 'DELETE') && uri[uri.length - 1] === '/') {
      throw "Don't " + method + " on directories!";
    }

    var promise = promising();
    var revision;

    headers['Authorization'] = 'Bearer ' + token;

    RS.WireClient.request(method, uri, {
      body: body,
      headers: headers
    }, function(error, response) {
      if (error) {
        promise.reject(error);
      } else {
        if ([401, 403, 404, 412].indexOf(response.status) >= 0) {
          promise.fulfill(response.status);
        } else if ([201, 204, 304].indexOf(response.status) >= 0 ||
                   (response.status === 200 && method !== 'GET')) {
          revision = response.getResponseHeader('ETag');
          promise.fulfill(response.status, undefined, undefined, revision);
        } else {
          var mimeType = response.getResponseHeader('Content-Type');
          var body;
          if (getEtag) {
            revision = response.getResponseHeader('ETag');
          } else {
            revision = response.status === 200 ? fakeRevision : undefined;
          }

          if ((! mimeType) || mimeType.match(/charset=binary/)) {
            readBinaryData(response.response, mimeType, function(result) {
              promise.fulfill(response.status, result, mimeType, revision);
            });
          } else {
            if (mimeType && mimeType.match(/^application\/json/)) {
              body = JSON.parse(response.responseText);
            } else {
              body = response.responseText;
            }
            promise.fulfill(response.status, body, mimeType, revision);
          }
        }
      }
    });
    return promise;
  }

  function readBinaryData(content, mimeType, callback) {
    var blob = new Blob([content], { type: mimeType });
    var reader = new FileReader();
    reader.addEventListener("loadend", function() {
      callback(reader.result); // reader.result contains the contents of blob as a typed array
    });
    reader.readAsArrayBuffer(blob);
  }

  function cleanPath(path) {
    return path.replace(/\/+/g, '/').split('/').map(encodeURIComponent).join('/');
  }

  function isFolderDescription(body) {
    return ((Object.keys(body).length === 2)
                && (body['@context'] === 'http://remotestorage.io/spec/folder-description')
                && (typeof(body['items']) === 'object'));
  }

  var onErrorCb;

  /**
   * Class : RemoteStorage.WireClient
   **/
  RS.WireClient = function(rs) {
    this.connected = false;
    /**
     * Event: change
     *   never fired for some reason
     *
     * Event: connected
     *   fired when the wireclient connect method realizes that it is
     *   in posession of a token and a href
     **/
    RS.eventHandling(this, 'change', 'connected');

    onErrorCb = function(error){
      if(error instanceof RemoteStorage.Unauthorized) {
        this.configure(undefined, undefined, undefined, null);
      }
    }.bind(this);
    rs.on('error', onErrorCb);
    if (haveLocalStorage) {
      var settings;
      try { settings = JSON.parse(localStorage[SETTINGS_KEY]); } catch(e) {}
      if (settings) {
        setTimeout(function() {
          this.configure(settings.userAddress, settings.href, settings.storageApi, settings.token);
        }.bind(this), 0);
      }
    }

    this._revisionCache = {};

    if (this.connected) {
      setTimeout(this._emit.bind(this), 0, 'connected');
    }
  };

  RS.WireClient.REQUEST_TIMEOUT = 30000;

  RS.WireClient.prototype = {
    /**
     * Property: token
     *
     * Holds the bearer token of this WireClient, as obtained in the OAuth dance
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.token
     *   // -> 'DEADBEEF01=='
     */

    /**
     * Property: href
     *
     * Holds the server's base URL, as obtained in the Webfinger discovery
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.href
     *   // -> 'https://storage.example.com/users/jblogg/'
     */

    /**
     * Property: storageApi
     *
     * Holds the spec version the server claims to be compatible with
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.storageApi
     *   // -> 'draft-dejong-remotestorage-01'
     */

    configure: function(userAddress, href, storageApi, token) {
      if (typeof(userAddress) !== 'undefined') {
        this.userAddress = userAddress;
      }
      if (typeof(href) !== 'undefined') {
        this.href = href;
      }
      if (typeof(storageApi) !== 'undefined') {
        this.storageApi = storageApi;
      }
      if (typeof(token) !== 'undefined') {
        this.token = token;
      }
      if (typeof(this.storageApi) !== 'undefined') {
        this._storageApi = STORAGE_APIS[this.storageApi] || API_HEAD;
        this.supportsRevs = this._storageApi >= API_00;
      }
      if (this.href && this.token) {
        this.connected = true;
        this._emit('connected');
      } else {
        this.connected = false;
      }
      if (haveLocalStorage) {
        localStorage[SETTINGS_KEY] = JSON.stringify({
          userAddress: this.userAddress,
          href: this.href,
          token: this.token,
          storageApi: this.storageApi
        });
      }
      RS.WireClient.configureHooks.forEach(function(hook) {
        hook.call(this);
      }.bind(this));
    },

    get: function(path, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      var headers = {};
      if (this.supportsRevs) {
        if (options.ifNoneMatch) {
          headers['If-None-Match'] = options.ifNoneMatch;
        }
      } else if (options.ifNoneMatch) {
        var oldRev = this._revisionCache[path];
        if (oldRev === options.ifNoneMatch) {
          // since sync descends for allKeys(local, remote), this causes
          // https://github.com/remotestorage/remotestorage.js/issues/399
          // commenting this out so that it gets the actual 404 from the
          // server. this only affects legacy servers
          // (this.supportsRevs==false):

          // return promising().fulfill(412);
          // FIXME empty block and commented code
        }
      }
      var promise = request('GET', this.href + cleanPath(path), this.token, headers,
                            undefined, this.supportsRevs, this._revisionCache[path]);
      if (this.supportsRevs || path.substr(-1) !== '/') {
        return promise;
      } else {
        return promise.then(function(status, body, contentType, revision) {
          var tmp;
          if (status === 200 && typeof(body) === 'object') {
            if (Object.keys(body).length === 0) {
              // no children (coerce response to 'not found')
              status = 404;
            } else if(isFolderDescription(body)) {
              tmp = {};
              for(var item in body.items) {
                this._revisionCache[path + item] = body.items[item].ETag;
                tmp[item] = body.items[item].ETag;
              }
              body = tmp;
            } else {//pre-02 server
              for(var key in body) {
                this._revisionCache[path + key] = body[key];
              }
            }
          }
          return promising().fulfill(status, body, contentType, revision);
        }.bind(this));
      }
    },

    put: function(path, body, contentType, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      if (!contentType.match(/charset=/)) {
        contentType += '; charset=' + ((body instanceof ArrayBuffer || isArrayBufferView(body)) ? 'binary' : 'utf-8');
      }
      var headers = { 'Content-Type': contentType };
      if (this.supportsRevs) {
        if (options.ifMatch) {
          headers['If-Match'] = options.ifMatch;
        }
        if (options.ifNoneMatch) {
          headers['If-None-Match'] = options.ifNoneMatch;
        }
      }
      return request('PUT', this.href + cleanPath(path), this.token,
                     headers, body, this.supportsRevs);
    },

    'delete': function(path, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      var headers = {};
      if (this.supportsRevs) {
        if (options.ifMatch) {
          headers['If-Match'] = options.ifMatch;
        }
      }
      return request('DELETE', this.href + cleanPath(path), this.token,
                     headers,
                     undefined, this.supportsRevs);
    }
  };

  // Shared cleanPath used by Dropbox
  RS.WireClient.cleanPath = cleanPath;

  // Shared isArrayBufferView used by WireClient and Dropbox
  RS.WireClient.isArrayBufferView = isArrayBufferView;

  // Shared request function used by WireClient, GoogleDrive and Dropbox.
  RS.WireClient.request = function(method, url, options, callback) {
    RemoteStorage.log(method, url);

    callback = callback.bind(this);

    var timedOut = false;

    var timer = setTimeout(function() {
      timedOut = true;
      callback('timeout');
    }, RS.WireClient.REQUEST_TIMEOUT);

    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true);

    if (options.responseType) {
      xhr.responseType = options.responseType;
    }
    if (options.headers) {
      for(var key in options.headers) {
        xhr.setRequestHeader(key, options.headers[key]);
      }
    }

    xhr.onload = function() {
      if (timedOut) { return; }
      clearTimeout(timer);
      callback(null, xhr);
    };

    xhr.onerror = function(error) {
      if (timedOut) { return; }
      clearTimeout(timer);
      callback(error);
    };

    var body = options.body;

    if (typeof(body) === 'object') {
      if (isArrayBufferView(body)) {
        /* alright. */
        //FIXME empty block
      }
      else if (body instanceof ArrayBuffer) {
        body = new Uint8Array(body);
      } else {
        body = JSON.stringify(body);
      }
    }
    xhr.send(body);
  };

  RS.WireClient.configureHooks = [];

  RS.WireClient._rs_init = function(remoteStorage) {
    remoteStorage.remote = new RS.WireClient(remoteStorage);
  };

  RS.WireClient._rs_supported = function() {
    haveLocalStorage = 'localStorage' in global;
    return !! global.XMLHttpRequest;
  };

  RS.WireClient._rs_cleanup = function(remoteStorage){
    if (haveLocalStorage){
      delete localStorage[SETTINGS_KEY];
    }
    remoteStorage.removeEventListener('error', onErrorCb);
  };

})(typeof(window) !== 'undefined' ? window : global);
<commit_msg>Add remotestorage-02 spec to list of storage APIs<commit_after>(function(global) {
  var RS = RemoteStorage;

  /**
   * Class: RemoteStorage.WireClient
   *
   * WireClient Interface
   * --------------------
   *
   * This file exposes a get/put/delete interface on top of XMLHttpRequest.
   * It requires to be configured with parameters about the remotestorage server to
   * connect to.
   * Each instance of WireClient is always associated with a single remotestorage
   * server and access token.
   *
   * Usually the WireClient instance can be accessed via `remoteStorage.remote`.
   *
   * This is the get/put/delete interface:
   *
   *   - #get() takes a path and optionally a ifNoneMatch option carrying a version
   *     string to check. It returns a promise that will be fulfilled with the HTTP
   *     response status, the response body, the MIME type as returned in the
   *     'Content-Type' header and the current revision, as returned in the 'ETag'
   *     header.
   *   - #put() takes a path, the request body and a content type string. It also
   *     accepts the ifMatch and ifNoneMatch options, that map to the If-Match and
   *     If-None-Match headers respectively. See the remotestorage-01 specification
   *     for details on handling these headers. It returns a promise, fulfilled with
   *     the same values as the one for #get().
   *   - #delete() takes a path and the ifMatch option as well. It returns a promise
   *     fulfilled with the same values as the one for #get().
   *
   * In addition to this, the WireClient has some compatibility features to work with
   * remotestorage 2012.04 compatible storages. For example it will cache revisions
   * from directory listings in-memory and return them accordingly as the "revision"
   * parameter in response to #get() requests. Similarly it will return 404 when it
   * receives an empty directory listing, to mimic remotestorage-01 behavior. Note
   * that it is not always possible to know the revision beforehand, hence it may
   * be undefined at times (especially for caching-roots).
   */

  var haveLocalStorage;
  var SETTINGS_KEY = "remotestorage:wireclient";

  var API_2012 = 1, API_00 = 2, API_01 = 3, API_02 = 4, API_HEAD = 5;

  var STORAGE_APIS = {
    'draft-dejong-remotestorage-00': API_00,
    'draft-dejong-remotestorage-01': API_01,
    'draft-dejong-remotestorage-02': API_02,
    'https://www.w3.org/community/rww/wiki/read-write-web-00#simple': API_2012
  };

  var isArrayBufferView;

  if (typeof(ArrayBufferView) === 'function') {
    isArrayBufferView = function(object) { return object && (object instanceof ArrayBufferView); };
  } else {
    var arrayBufferViews = [
      Int8Array, Uint8Array, Int16Array, Uint16Array,
      Int32Array, Uint32Array, Float32Array, Float64Array
    ];
    isArrayBufferView = function(object) {
      for(var i=0;i<8;i++) {
        if (object instanceof arrayBufferViews[i]) {
          return true;
        }
      }
      return false;
    };
  }

  function request(method, uri, token, headers, body, getEtag, fakeRevision) {
    if ((method === 'PUT' || method === 'DELETE') && uri[uri.length - 1] === '/') {
      throw "Don't " + method + " on directories!";
    }

    var promise = promising();
    var revision;

    headers['Authorization'] = 'Bearer ' + token;

    RS.WireClient.request(method, uri, {
      body: body,
      headers: headers
    }, function(error, response) {
      if (error) {
        promise.reject(error);
      } else {
        if ([401, 403, 404, 412].indexOf(response.status) >= 0) {
          promise.fulfill(response.status);
        } else if ([201, 204, 304].indexOf(response.status) >= 0 ||
                   (response.status === 200 && method !== 'GET')) {
          revision = response.getResponseHeader('ETag');
          promise.fulfill(response.status, undefined, undefined, revision);
        } else {
          var mimeType = response.getResponseHeader('Content-Type');
          var body;
          if (getEtag) {
            revision = response.getResponseHeader('ETag');
          } else {
            revision = response.status === 200 ? fakeRevision : undefined;
          }

          if ((! mimeType) || mimeType.match(/charset=binary/)) {
            readBinaryData(response.response, mimeType, function(result) {
              promise.fulfill(response.status, result, mimeType, revision);
            });
          } else {
            if (mimeType && mimeType.match(/^application\/json/)) {
              body = JSON.parse(response.responseText);
            } else {
              body = response.responseText;
            }
            promise.fulfill(response.status, body, mimeType, revision);
          }
        }
      }
    });
    return promise;
  }

  function readBinaryData(content, mimeType, callback) {
    var blob = new Blob([content], { type: mimeType });
    var reader = new FileReader();
    reader.addEventListener("loadend", function() {
      callback(reader.result); // reader.result contains the contents of blob as a typed array
    });
    reader.readAsArrayBuffer(blob);
  }

  function cleanPath(path) {
    return path.replace(/\/+/g, '/').split('/').map(encodeURIComponent).join('/');
  }

  function isFolderDescription(body) {
    return ((Object.keys(body).length === 2)
                && (body['@context'] === 'http://remotestorage.io/spec/folder-description')
                && (typeof(body['items']) === 'object'));
  }

  var onErrorCb;

  /**
   * Class : RemoteStorage.WireClient
   **/
  RS.WireClient = function(rs) {
    this.connected = false;
    /**
     * Event: change
     *   never fired for some reason
     *
     * Event: connected
     *   fired when the wireclient connect method realizes that it is
     *   in posession of a token and a href
     **/
    RS.eventHandling(this, 'change', 'connected');

    onErrorCb = function(error){
      if(error instanceof RemoteStorage.Unauthorized) {
        this.configure(undefined, undefined, undefined, null);
      }
    }.bind(this);
    rs.on('error', onErrorCb);
    if (haveLocalStorage) {
      var settings;
      try { settings = JSON.parse(localStorage[SETTINGS_KEY]); } catch(e) {}
      if (settings) {
        setTimeout(function() {
          this.configure(settings.userAddress, settings.href, settings.storageApi, settings.token);
        }.bind(this), 0);
      }
    }

    this._revisionCache = {};

    if (this.connected) {
      setTimeout(this._emit.bind(this), 0, 'connected');
    }
  };

  RS.WireClient.REQUEST_TIMEOUT = 30000;

  RS.WireClient.prototype = {
    /**
     * Property: token
     *
     * Holds the bearer token of this WireClient, as obtained in the OAuth dance
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.token
     *   // -> 'DEADBEEF01=='
     */

    /**
     * Property: href
     *
     * Holds the server's base URL, as obtained in the Webfinger discovery
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.href
     *   // -> 'https://storage.example.com/users/jblogg/'
     */

    /**
     * Property: storageApi
     *
     * Holds the spec version the server claims to be compatible with
     *
     * Example:
     *   (start code)
     *
     *   remoteStorage.remote.storageApi
     *   // -> 'draft-dejong-remotestorage-01'
     */

    configure: function(userAddress, href, storageApi, token) {
      if (typeof(userAddress) !== 'undefined') {
        this.userAddress = userAddress;
      }
      if (typeof(href) !== 'undefined') {
        this.href = href;
      }
      if (typeof(storageApi) !== 'undefined') {
        this.storageApi = storageApi;
      }
      if (typeof(token) !== 'undefined') {
        this.token = token;
      }
      if (typeof(this.storageApi) !== 'undefined') {
        this._storageApi = STORAGE_APIS[this.storageApi] || API_HEAD;
        this.supportsRevs = this._storageApi >= API_00;
      }
      if (this.href && this.token) {
        this.connected = true;
        this._emit('connected');
      } else {
        this.connected = false;
      }
      if (haveLocalStorage) {
        localStorage[SETTINGS_KEY] = JSON.stringify({
          userAddress: this.userAddress,
          href: this.href,
          token: this.token,
          storageApi: this.storageApi
        });
      }
      RS.WireClient.configureHooks.forEach(function(hook) {
        hook.call(this);
      }.bind(this));
    },

    get: function(path, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      var headers = {};
      if (this.supportsRevs) {
        if (options.ifNoneMatch) {
          headers['If-None-Match'] = options.ifNoneMatch;
        }
      } else if (options.ifNoneMatch) {
        var oldRev = this._revisionCache[path];
        if (oldRev === options.ifNoneMatch) {
          // since sync descends for allKeys(local, remote), this causes
          // https://github.com/remotestorage/remotestorage.js/issues/399
          // commenting this out so that it gets the actual 404 from the
          // server. this only affects legacy servers
          // (this.supportsRevs==false):

          // return promising().fulfill(412);
          // FIXME empty block and commented code
        }
      }
      var promise = request('GET', this.href + cleanPath(path), this.token, headers,
                            undefined, this.supportsRevs, this._revisionCache[path]);
      if (this.supportsRevs || path.substr(-1) !== '/') {
        return promise;
      } else {
        return promise.then(function(status, body, contentType, revision) {
          var tmp;
          if (status === 200 && typeof(body) === 'object') {
            if (Object.keys(body).length === 0) {
              // no children (coerce response to 'not found')
              status = 404;
            } else if(isFolderDescription(body)) {
              tmp = {};
              for(var item in body.items) {
                this._revisionCache[path + item] = body.items[item].ETag;
                tmp[item] = body.items[item].ETag;
              }
              body = tmp;
            } else {//pre-02 server
              for(var key in body) {
                this._revisionCache[path + key] = body[key];
              }
            }
          }
          return promising().fulfill(status, body, contentType, revision);
        }.bind(this));
      }
    },

    put: function(path, body, contentType, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      if (!contentType.match(/charset=/)) {
        contentType += '; charset=' + ((body instanceof ArrayBuffer || isArrayBufferView(body)) ? 'binary' : 'utf-8');
      }
      var headers = { 'Content-Type': contentType };
      if (this.supportsRevs) {
        if (options.ifMatch) {
          headers['If-Match'] = options.ifMatch;
        }
        if (options.ifNoneMatch) {
          headers['If-None-Match'] = options.ifNoneMatch;
        }
      }
      return request('PUT', this.href + cleanPath(path), this.token,
                     headers, body, this.supportsRevs);
    },

    'delete': function(path, options) {
      if (!this.connected) {
        throw new Error("not connected (path: " + path + ")");
      }
      if (!options) { options = {}; }
      var headers = {};
      if (this.supportsRevs) {
        if (options.ifMatch) {
          headers['If-Match'] = options.ifMatch;
        }
      }
      return request('DELETE', this.href + cleanPath(path), this.token,
                     headers,
                     undefined, this.supportsRevs);
    }
  };

  // Shared cleanPath used by Dropbox
  RS.WireClient.cleanPath = cleanPath;

  // Shared isArrayBufferView used by WireClient and Dropbox
  RS.WireClient.isArrayBufferView = isArrayBufferView;

  // Shared request function used by WireClient, GoogleDrive and Dropbox.
  RS.WireClient.request = function(method, url, options, callback) {
    RemoteStorage.log(method, url);

    callback = callback.bind(this);

    var timedOut = false;

    var timer = setTimeout(function() {
      timedOut = true;
      callback('timeout');
    }, RS.WireClient.REQUEST_TIMEOUT);

    var xhr = new XMLHttpRequest();
    xhr.open(method, url, true);

    if (options.responseType) {
      xhr.responseType = options.responseType;
    }
    if (options.headers) {
      for(var key in options.headers) {
        xhr.setRequestHeader(key, options.headers[key]);
      }
    }

    xhr.onload = function() {
      if (timedOut) { return; }
      clearTimeout(timer);
      callback(null, xhr);
    };

    xhr.onerror = function(error) {
      if (timedOut) { return; }
      clearTimeout(timer);
      callback(error);
    };

    var body = options.body;

    if (typeof(body) === 'object') {
      if (isArrayBufferView(body)) {
        /* alright. */
        //FIXME empty block
      }
      else if (body instanceof ArrayBuffer) {
        body = new Uint8Array(body);
      } else {
        body = JSON.stringify(body);
      }
    }
    xhr.send(body);
  };

  RS.WireClient.configureHooks = [];

  RS.WireClient._rs_init = function(remoteStorage) {
    remoteStorage.remote = new RS.WireClient(remoteStorage);
  };

  RS.WireClient._rs_supported = function() {
    haveLocalStorage = 'localStorage' in global;
    return !! global.XMLHttpRequest;
  };

  RS.WireClient._rs_cleanup = function(remoteStorage){
    if (haveLocalStorage){
      delete localStorage[SETTINGS_KEY];
    }
    remoteStorage.removeEventListener('error', onErrorCb);
  };

})(typeof(window) !== 'undefined' ? window : global);
<|endoftext|>


<commit_before>/**************JQUERY FUNCTIONS******************/
jQuery.fn.center = function () {
    this.css("position","absolute");
    this.css("top", (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop() + "px");
    this.css("left", (( $(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px");

    return this;
};

jQuery.fn.inside_center = function () {
    var top = ((this.parent().height() - this.outerHeight()) / 2);
    var left = (( this.parent().width() - this.outerWidth() ) / 2);
    this.parent().css("position","relative");
    this.css("position","absolute");
    this.css("top", top + "px");
    this.css("left", left + "px");
    return this;
};

jQuery.fn.verticalCenter = function(){
    this.each(function() {
        var parent_height = $(this).parent().height();
        var height = $(this).outerHeight();

        $(this).removeClass('verticalCenter');
        if(height < parent_height){
            var top_margin = (parent_height - height)/2;
            $(this).css("marginTop",top_margin+'px');
        }
    });
}

jQuery.fn.verticalCenter = function(){
    this.each(function() {
        var parent_height = $(this).parent().height();
        var height = $(this).outerHeight();

        $(this).removeClass('verticalCenter');
        if(height < parent_height){
            var top_margin = (parent_height - height)/2;
            $(this).css("marginTop",top_margin+'px');
        }
    });
}

jQuery.fn.equalHeights = function(minHeight, maxHeight, callback) {
    if (typeof minHeight !== 'function') {tallest = (minHeight) ? minHeight : 0;}

    this.each(function() {
        if($(this).innerHeight() > tallest) {
                tallest = $(this).innerHeight();
        }
    });
    if((maxHeight) && typeof maxHeight !== 'function' && tallest < maxHeight) tallest = maxHeight; // Corregido '>'

    this.each(function() {
        padding = $(this).innerHeight() - $(this).height();
        if(padding > 0){$(this).height(tallest-padding).css("overflow","auto");}
        else{$(this).height(tallest).css("overflow","auto");}
    });

    // Callback function
    if (typeof minHeight === 'function') {
        minHeight();
    }else if (typeof maxHeight === 'function') {
        maxHeight();
    }else if (typeof callback === 'function') {
        callback();
    }
    return true;
}

jQuery.fn.squared = function(){
    this.each(function() {
        var w = $(this).width();
        $(this).height(w);
    });
}

jQuery.fn.reset = function () {
  $(this).each (function() { this.reset(); });
}

jQuery.fn.print = function(){
    var frame_name = ("printer-" + (new Date()).getTime());
    var frame_html = $( "" );
    frame_html.css({
        "width":"1px",
        "height":"1px",
        "position":"absolute",
        "left":"-9999px"
    }).appendTo( $("body:first"));
    var frame = window.frames[ frame_name ];
    var frame_doc = frame.document;
    var style = $( "
" ).append($( "style" ).clone());

    frame_doc.open();
    frame_doc.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><title>" );
    frame_doc.write( document.title );
    frame_doc.write( "</title><link href=\"files/style.css\" rel=\"stylesheet\" type=\"text/css\" />" );
    frame_doc.write( "
" );
    frame_doc.write( this.html() );
    frame_doc.write( "
" );
    frame_doc.close();
    frame.focus();
    frame.print();

    setTimeout(function(){
        frame_html.remove();
    },(60 * 1000));
}

jQuery.fn.export_excel = function(path_export_file){
    $("body:first").append(' <form method="post" lang="es" target="_blank" action="'+path_export_file+'" id="export_excel" style="display:none;"><input name="name" type="hidden" value="" /><input name="data" type="hidden" value="" /></form>');
    $('#export_excel input[name="name"]').val( $(this).closest('.box').find('header span.text').html());
    $('#export_excel input[name="data"]').val( $("
").append( $(this).clone()).html());
    $("#export_excel").submit().remove();
}

jQuery.fn.export_csv = function(path_export_file) {
  var data = $(this).first();
  var csvData = [];
  var tmpArr = [];
  var tmpStr = '';

  if(_bhl.split('-')[0] === 'es'){var list_delimiter = ';';}
  else{var list_delimiter = ',';}

  data.find("tr").each(function() {
      if($(this).find("th").length) {
          $(this).find("th").each(function() {
            tmpStr = $(this).text().replace(/"/g, '""');
            tmpArr.push('"' + tmpStr + '"');
          });
          csvData.push(tmpArr.join(list_delimiter));
      } else {
          tmpArr = [];
             $(this).find("td").each(function() {
                  if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
                      tmpArr.push(parseFloat($(this).text()));
                  } else {
                      tmpStr = $(this).text().replace(/"/g, '""');
                      tmpArr.push('"' + tmpStr + '"');
                  }
             });
          csvData.push(tmpArr.join(list_delimiter));
      }
  });
  var output = csvData.join('\n');
  var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);

  $("body:first").append('<form method="post" lang="es" target="_blank" action="'+path_export_file+'" id="export_excel" style="display:none;"><input name="name" type="hidden" value="" /><input name="data" type="hidden" value="" /></form>');
    $('#export_excel input[name="name"]').val( $(this).closest('.box').find('header span.text').html());
    $('#export_excel input[name="data"]').val(output);
    $("#export_excel").submit().remove();
}

var valid = true;
var emailreg = /^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/;
var msgi = "";
var msgi_c = "INCOMPLETOS:\r\n";
var msgc = "";
var msgc_c = "\r\nINCORRECTOS:\r\n";
var msg = "";

jQuery.fn.Vform = function() {
    $(this).find('.Vtext').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).find('.Vnumber').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).find('.Vemail').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).bind("submit",function(){
        valid = true;
        msgi = "";
        msgc = "";
        msg="";
        var label_present = false;
        var tmp = "";
        var index = 0;
        if($(this).find('input[name=itm_label_in_value]').val() == "1"){
            label_present = true;
        }
        $(this).find('.Vtext').each(function(){
            if($(this).val() == $(this).attr('alt') || $(this).attr('alt') == undefined){
                msgi = msgi+$(this).attr('name')+": no ha sido completado. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vselect').each(function(){
            if($(this).val() == "0"){
                msgi = msgi+$(this).attr('name')+": no se ha seleccionado ningún valor. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vemail').each(function(){
            tmp = $(this).val();
            if(label_present == true){
                index = tmp.indexOf(":");
                tmp = tmp.substr(index+1);
                tmp = $.trim(tmp);
            }
            if( !emailreg.test(tmp) ){
                msgc = msgc+$(this).attr('name')+": no es una dirección de email válida. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vnumber').each(function(){
            tmp = $(this).val();
            if(label_present){
                index = tmp.indexOf(":");
                tmp = tmp.substr(index+1);
                tmp = $.trim(tmp);
            }
            if( isNaN(parseInt(tmp)) || tmp.length == 0){
                msgc = msgc+$(this).attr('name')+": no es correcto, solo debe contener números. \r\n";
                valid = false;
            }
        });
        if(msgi.length != 0){
            msg = msg+msgi_c+msgi;
        }
        if(msgc.length != 0){
            msg = msg+msgc_c+msgc;
        }
        if(valid == false){
            alert(msg);
            return false;
        }
    });
}
/*******************FUNCTIONS**********************/
function controlViewport(){
    if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
        var viewportmeta = document.querySelector('meta[name="viewport"]');
        if (viewportmeta) {
            viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0';
            document.body.addEventListener('gesturestart', function () {
                viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
            }, false);
        }
    }
}

function clock(){
    $('.clock').each(function(){
        var h = parseInt($(this).find('.h').html(),10);
        var m = parseInt($(this).find('.m').html(),10);
        var s = parseInt($(this).find('.s').html(),10);

        s++;
        if(s == 60){
            s=0;
            m++;
        }
        if(m == 60){
            m=0;
            h++;
        }
        if(h == 24){
            h=0;
        }

        if(s < 10){
            $(this).find('.s').html('0'+s);
        }else{
            $(this).find('.s').html(s);
        }
        if(m < 10){
            $(this).find('.m').html('0'+m);
        }else{
            $(this).find('.m').html(m);
        }
        if(h < 10){
            $(this).find('.h').html('0'+h);
        }else{
            $(this).find('.h').html(h);
        }
    });
}

function full_screen(element) {
  if(element.requestFullscreen) {
    element.requestFullscreen();
  } else if(element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
  } else if(element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen();
  } else if(element.msRequestFullscreen) {
    element.msRequestFullscreen();
  }
}

function exit_full_screen() {
  if(document.exitFullscreen) {
    document.exitFullscreen();
  } else if(document.mozCancelFullScreen) {
    document.mozCancelFullScreen();
  } else if(document.webkitExitFullscreen) {
    document.webkitExitFullscreen();
  }
}

function toggle_full_screen(element){
    if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {
        full_screen(element);
    }else{
        exit_full_screen();
    }
}

function genQuickNav(){
    quick_nav = {};
    quick_nav['Home'] = '/';
    $('.quick-nav').each(function(){
        var a = $(this).find('a');
        a.each(function(){
            quick_nav[$(this).html()] = $(this).attr('href');
        });
    });
    return quick_nav;
}

function createQuickNav(target){
    quick_nav = genQuickNav();
    nav_html = '

Menú de navegación
';
    for(var link in quick_nav){
        nav_html += ''+link+'';
    }
    nav_html += '
';
    target.prepend(nav_html);
}

/**********************TRIGGERS**********************/

$(document).on('click','#btn_quick_nav',function(){
    if($('#quick_nav').is(":visible")){
        $('#quick_nav').hide('fast');
    }else{
        $('#quick_nav').show('fast');
    }
});

$(document).on('click','#quick_nav a',function(){
    $('#quick_nav').hide('fast');
});<commit_msg>Added trigger for equalHeights.<commit_after>/**************JQUERY FUNCTIONS******************/
jQuery.fn.center = function () {
    this.css("position","absolute");
    this.css("top", (($(window).height() - this.outerHeight()) / 2) + $(window).scrollTop() + "px");
    this.css("left", (( $(window).width() - this.outerWidth()) / 2) + $(window).scrollLeft() + "px");

    return this;
};

jQuery.fn.inside_center = function () {
    var top = ((this.parent().height() - this.outerHeight()) / 2);
    var left = (( this.parent().width() - this.outerWidth() ) / 2);
    this.parent().css("position","relative");
    this.css("position","absolute");
    this.css("top", top + "px");
    this.css("left", left + "px");
    return this;
};

jQuery.fn.verticalCenter = function(){
    this.each(function() {
        var parent_height = $(this).parent().height();
        var height = $(this).outerHeight();

        $(this).removeClass('verticalCenter');
        if(height < parent_height){
            var top_margin = (parent_height - height)/2;
            $(this).css("marginTop",top_margin+'px');
        }
    });
}

jQuery.fn.equalHeights = function(minHeight, maxHeight, callback) {
    if (typeof minHeight !== 'function') {tallest = (minHeight) ? minHeight : 0;}

    this.each(function() {
        if($(this).innerHeight() > tallest) {
                tallest = $(this).innerHeight();
        }
    });
    if((maxHeight) && typeof maxHeight !== 'function' && tallest < maxHeight) tallest = maxHeight; // Corregido '>'

    this.each(function() {
        padding = $(this).innerHeight() - $(this).height();
        if(padding > 0){$(this).height(tallest-padding).css("overflow","auto");}
        else{$(this).height(tallest).css("overflow","auto");}
    });

    // Callback function
    if (typeof minHeight === 'function') {
        minHeight();
    }else if (typeof maxHeight === 'function') {
        maxHeight();
    }else if (typeof callback === 'function') {
        callback();
    }
    return true;
}

jQuery.fn.squared = function(){
    this.each(function() {
        var w = $(this).width();
        $(this).height(w);
    });
}

jQuery.fn.reset = function () {
  $(this).each (function() { this.reset(); });
}

jQuery.fn.print = function(){
    var frame_name = ("printer-" + (new Date()).getTime());
    var frame_html = $( "" );
    frame_html.css({
        "width":"1px",
        "height":"1px",
        "position":"absolute",
        "left":"-9999px"
    }).appendTo( $("body:first"));
    var frame = window.frames[ frame_name ];
    var frame_doc = frame.document;
    var style = $( "
" ).append($( "style" ).clone());

    frame_doc.open();
    frame_doc.write( "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\"><title>" );
    frame_doc.write( document.title );
    frame_doc.write( "</title><link href=\"files/style.css\" rel=\"stylesheet\" type=\"text/css\" />" );
    frame_doc.write( "
" );
    frame_doc.write( this.html() );
    frame_doc.write( "
" );
    frame_doc.close();
    frame.focus();
    frame.print();

    setTimeout(function(){
        frame_html.remove();
    },(60 * 1000));
}

jQuery.fn.export_excel = function(path_export_file){
    $("body:first").append(' <form method="post" lang="es" target="_blank" action="'+path_export_file+'" id="export_excel" style="display:none;"><input name="name" type="hidden" value="" /><input name="data" type="hidden" value="" /></form>');
    $('#export_excel input[name="name"]').val( $(this).closest('.box').find('header span.text').html());
    $('#export_excel input[name="data"]').val( $("
").append( $(this).clone()).html());
    $("#export_excel").submit().remove();
}

jQuery.fn.export_csv = function(path_export_file) {
  var data = $(this).first();
  var csvData = [];
  var tmpArr = [];
  var tmpStr = '';

  if(_bhl.split('-')[0] === 'es'){var list_delimiter = ';';}
  else{var list_delimiter = ',';}

  data.find("tr").each(function() {
      if($(this).find("th").length) {
          $(this).find("th").each(function() {
            tmpStr = $(this).text().replace(/"/g, '""');
            tmpArr.push('"' + tmpStr + '"');
          });
          csvData.push(tmpArr.join(list_delimiter));
      } else {
          tmpArr = [];
             $(this).find("td").each(function() {
                  if($(this).text().match(/^-{0,1}\d*\.{0,1}\d+$/)) {
                      tmpArr.push(parseFloat($(this).text()));
                  } else {
                      tmpStr = $(this).text().replace(/"/g, '""');
                      tmpArr.push('"' + tmpStr + '"');
                  }
             });
          csvData.push(tmpArr.join(list_delimiter));
      }
  });
  var output = csvData.join('\n');
  var uri = 'data:application/csv;charset=UTF-8,' + encodeURIComponent(output);

  $("body:first").append('<form method="post" lang="es" target="_blank" action="'+path_export_file+'" id="export_excel" style="display:none;"><input name="name" type="hidden" value="" /><input name="data" type="hidden" value="" /></form>');
    $('#export_excel input[name="name"]').val( $(this).closest('.box').find('header span.text').html());
    $('#export_excel input[name="data"]').val(output);
    $("#export_excel").submit().remove();
}

var valid = true;
var emailreg = /^[a-zA-Z0-9_\.\-]+@[a-zA-Z0-9\-]+\.[a-zA-Z0-9\-\.]+$/;
var msgi = "";
var msgi_c = "INCOMPLETOS:\r\n";
var msgc = "";
var msgc_c = "\r\nINCORRECTOS:\r\n";
var msg = "";

jQuery.fn.Vform = function() {
    $(this).find('.Vtext').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).find('.Vnumber').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).find('.Vemail').each(function(){
        $(this).attr('alt',$(this).val());
    });

    $(this).bind("submit",function(){
        valid = true;
        msgi = "";
        msgc = "";
        msg="";
        var label_present = false;
        var tmp = "";
        var index = 0;
        if($(this).find('input[name=itm_label_in_value]').val() == "1"){
            label_present = true;
        }
        $(this).find('.Vtext').each(function(){
            if($(this).val() == $(this).attr('alt') || $(this).attr('alt') == undefined){
                msgi = msgi+$(this).attr('name')+": no ha sido completado. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vselect').each(function(){
            if($(this).val() == "0"){
                msgi = msgi+$(this).attr('name')+": no se ha seleccionado ningún valor. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vemail').each(function(){
            tmp = $(this).val();
            if(label_present == true){
                index = tmp.indexOf(":");
                tmp = tmp.substr(index+1);
                tmp = $.trim(tmp);
            }
            if( !emailreg.test(tmp) ){
                msgc = msgc+$(this).attr('name')+": no es una dirección de email válida. \r\n";
                valid = false;
            }
        });
        $(this).find('.Vnumber').each(function(){
            tmp = $(this).val();
            if(label_present){
                index = tmp.indexOf(":");
                tmp = tmp.substr(index+1);
                tmp = $.trim(tmp);
            }
            if( isNaN(parseInt(tmp)) || tmp.length == 0){
                msgc = msgc+$(this).attr('name')+": no es correcto, solo debe contener números. \r\n";
                valid = false;
            }
        });
        if(msgi.length != 0){
            msg = msg+msgi_c+msgi;
        }
        if(msgc.length != 0){
            msg = msg+msgc_c+msgc;
        }
        if(valid == false){
            alert(msg);
            return false;
        }
    });
}
/*******************FUNCTIONS**********************/
function controlViewport(){
    if (navigator.userAgent.match(/iPhone/i) || navigator.userAgent.match(/iPad/i)) {
        var viewportmeta = document.querySelector('meta[name="viewport"]');
        if (viewportmeta) {
            viewportmeta.content = 'width=device-width, minimum-scale=1.0, maximum-scale=1.0, initial-scale=1.0';
            document.body.addEventListener('gesturestart', function () {
                viewportmeta.content = 'width=device-width, minimum-scale=0.25, maximum-scale=1.6';
            }, false);
        }
    }
}

function clock(){
    $('.clock').each(function(){
        var h = parseInt($(this).find('.h').html(),10);
        var m = parseInt($(this).find('.m').html(),10);
        var s = parseInt($(this).find('.s').html(),10);

        s++;
        if(s == 60){
            s=0;
            m++;
        }
        if(m == 60){
            m=0;
            h++;
        }
        if(h == 24){
            h=0;
        }

        if(s < 10){
            $(this).find('.s').html('0'+s);
        }else{
            $(this).find('.s').html(s);
        }
        if(m < 10){
            $(this).find('.m').html('0'+m);
        }else{
            $(this).find('.m').html(m);
        }
        if(h < 10){
            $(this).find('.h').html('0'+h);
        }else{
            $(this).find('.h').html(h);
        }
    });
}

function full_screen(element) {
  if(element.requestFullscreen) {
    element.requestFullscreen();
  } else if(element.mozRequestFullScreen) {
    element.mozRequestFullScreen();
  } else if(element.webkitRequestFullscreen) {
    element.webkitRequestFullscreen();
  } else if(element.msRequestFullscreen) {
    element.msRequestFullscreen();
  }
}

function exit_full_screen() {
  if(document.exitFullscreen) {
    document.exitFullscreen();
  } else if(document.mozCancelFullScreen) {
    document.mozCancelFullScreen();
  } else if(document.webkitExitFullscreen) {
    document.webkitExitFullscreen();
  }
}

function toggle_full_screen(element){
    if (!document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement ) {
        full_screen(element);
    }else{
        exit_full_screen();
    }
}

function genQuickNav(){
    quick_nav = {};
    quick_nav['Home'] = '/';
    $('.quick-nav').each(function(){
        var a = $(this).find('a');
        a.each(function(){
            quick_nav[$(this).html()] = $(this).attr('href');
        });
    });
    return quick_nav;
}

function createQuickNav(target){
    quick_nav = genQuickNav();
    nav_html = '

Menú de navegación
';
    for(var link in quick_nav){
        nav_html += ''+link+'';
    }
    nav_html += '
';
    target.prepend(nav_html);
}

/**********************TRIGGERS**********************/

$(document).on('click','#btn_quick_nav',function(){
    if($('#quick_nav').is(":visible")){
        $('#quick_nav').hide('fast');
    }else{
        $('#quick_nav').show('fast');
    }
});

$(document).on('click','#quick_nav a',function(){
    $('#quick_nav').hide('fast');
});

$(document).ready(function(){
    $('.equalHeights').equalHeights();
});<|endoftext|>


<commit_before>import {validate} from 'validate.js';
import {keysCheck, cardDate, custFormat, cardCheck, blazeCardCheck} from './validation/custom-validations';

const apiConfMap = {
    sandboxConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'https://sandboxadmin.citruspay.com/service',
        adminUrl : 'https://sandboxadmin.citruspay.com',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://sandboxmars.citruspay.com/dynamic-pricing/dynamicpricing'
    },
    prodConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblaze.citruspay.com',
        motoApiUrl: 'https://admin.citruspay.com/service',
        adminUrl : 'https://admin.citruspay.com',
        MCPAPIUrl: 'https://mercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://mars.citruspay.com/dynamicpricing/dynamicpricing'
    },
    stagingConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'https://stgadmin2.citruspay.com/service',
        adminUrl : 'https://stgadmin2.citruspay.com',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://sandboxmars.citruspay.com/dynamic-pricing/dynamicpricing'
    },
    localConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'http://localhost:8080/admin-site/service',
        adminUrl : 'http://localhost:8080/admin-site',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'http://localhost:8080/dynamic-pricing/dynamicpricing'
    }
};

const handlersMap = {
    errorHandler: (error) => { //default Error Handler
        if (console.error) {
            console.error('Error thrown from citrus.js sdk: ', error);
        } else {
            console.log('Error thrown from citrus.js sdk: ', error);
        }
    },
    serverErrorHandler: (error) => {
        console.error("Error from server. handled in default server error handler", JSON.stringify(error));
    },
    transactionHandler:(error) => {
        console.log("Transaction status :", error);
    }
};

let env = 'prod';

const configMap = {
    merchantAccessKey: '',
    vanityUrl: '',
    env: 'prod',
    blazeCardApiUrl: apiConfMap[env + 'Conf'].blazeCardApiUrl,
    blazeNetApiUrl: apiConfMap[env + 'Conf'].blazeNetApiUrl,
    motoApiUrl: apiConfMap[env + 'Conf'].motoApiUrl,
    MCPAPIUrl: apiConfMap[env + 'Conf'].MCPAPIUrl,
    dpApiUrl:apiConfMap[env+'Conf'].dpApiUrl,
    adminUrl: apiConfMap[env + 'Conf'].adminUrl
};

const setConfig = (configObj) => {
    configObj.env && (env = configObj.env);    Object.assign(configMap, {
        blazeCardApiUrl: apiConfMap[env+'Conf'].blazeCardApiUrl,
        blazeNetApiUrl: apiConfMap[env+'Conf'].blazeNetApiUrl,
        motoApiUrl : apiConfMap[env+'Conf'].motoApiUrl,
        MCPAPIUrl: apiConfMap[env+'Conf'].MCPAPIUrl,
        dpApiUrl:apiConfMap[env+'Conf'].dpApiUrl,
        adminUrl: apiConfMap[env + 'Conf'].adminUrl
    }, configObj)
    return Object.assign({}, configMap);
};

const getConfig = () => {
    return Object.assign({}, configMap);
};

const getParameterByName = (name, url) => {
    if (!url) url = window.location.href;
    url = url.toLowerCase(); // This is just to avoid case sensitiveness
    name = name.replace(/[\[\]]/g, "\\$&").toLowerCase();// This is just to avoid case sensitiveness for query parameter name
    let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
};

function getDeviceType() {
    let device = "WEB"; //initiate as web
    // device detection
    if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
        device = "MOBILE";
    }
    else {
        device = "DESKTOP";
    }
    return device;
}

const init = () => {
    validate.validators.keysCheck = keysCheck;
    validate.validators.cardDate = cardDate;
    validate.validators.cardCheck = cardCheck;
    validate.validators.blazeCardCheck = blazeCardCheck;
    validate.validators.custFormat = custFormat;
    let deviceType = getDeviceType();
    setConfig({deviceType});
    let responded = false;
    setConfig({responded});
    let page = "CJS";
    setConfig({page});

    //for back button cancellation scenario

    if (history && history.pushState) {
        if (getParameterByName('fromBank') === 'yes') {
            //console.log('for cancellation API ==> from bank! ', localStorage.getItem('blazeCardcancelRequestObj'));
            let urlWithQS = window.location.href;
            urlWithQS = urlWithQS.replace('&fromBank=yes', '');
            urlWithQS = urlWithQS.replace('fromBank=yes&', '');
            urlWithQS = urlWithQS.replace('?fromBank=yes', '');
            window.history.pushState({path: urlWithQS}, '', urlWithQS);
        }else {
        //console.log('for cancellation API ==> not from bank!');
        }
    }
};

export {init, handlersMap, configMap, setConfig, getConfig};<commit_msg>dp url change<commit_after>import {validate} from 'validate.js';
import {keysCheck, cardDate, custFormat, cardCheck, blazeCardCheck} from './validation/custom-validations';

const apiConfMap = {
    sandboxConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'https://sandboxadmin.citruspay.com/service',
        adminUrl : 'https://sandboxadmin.citruspay.com',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://sandboxmars.citruspay.com/dynamic-pricing/dynamicpricing'
    },
    prodConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblaze.citruspay.com',
        motoApiUrl: 'https://admin.citruspay.com/service',
        adminUrl : 'https://admin.citruspay.com',
        MCPAPIUrl: 'https://mercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://mars.citruspay.com/dynamicpricing/dynamicpricing'
    },
    stagingConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'https://stgadmin2.citruspay.com/service',
        adminUrl : 'https://stgadmin2.citruspay.com',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'https://stgadmin2.citruspay.com/dynamic-pricing/dynamicpricing'
    },
    localConf : {
        blazeCardApiUrl : 'https://blazecardsbox.citruspay.com',
        blazeNetApiUrl : 'https://sboxblazenet.citruspay.com',
        motoApiUrl: 'http://localhost:8080/admin-site/service',
        adminUrl : 'http://localhost:8080/admin-site',
        MCPAPIUrl: 'https://sboxmercury.citruspay.com/multi-currency-pricing/mcp/mcpForCurrencies',
        dpApiUrl: 'http://localhost:8080/dynamic-pricing/dynamicpricing'
    }
};

const handlersMap = {
    errorHandler: (error) => { //default Error Handler
        if (console.error) {
            console.error('Error thrown from citrus.js sdk: ', error);
        } else {
            console.log('Error thrown from citrus.js sdk: ', error);
        }
    },
    serverErrorHandler: (error) => {
        console.error("Error thrown from citrus.js sdk:", JSON.stringify(error));
    },
    transactionHandler:(response) => {
        console.log("Transaction status :", response);
    }
};

let env = 'prod';

const configMap = {
    merchantAccessKey: '',
    vanityUrl: '',
    env: 'prod',
    blazeCardApiUrl: apiConfMap[env + 'Conf'].blazeCardApiUrl,
    blazeNetApiUrl: apiConfMap[env + 'Conf'].blazeNetApiUrl,
    motoApiUrl: apiConfMap[env + 'Conf'].motoApiUrl,
    MCPAPIUrl: apiConfMap[env + 'Conf'].MCPAPIUrl,
    dpApiUrl:apiConfMap[env+'Conf'].dpApiUrl,
    adminUrl: apiConfMap[env + 'Conf'].adminUrl
};

const setConfig = (configObj) => {
    configObj.env && (env = configObj.env);
    Object.assign(configMap, {
        blazeCardApiUrl: apiConfMap[env+'Conf'].blazeCardApiUrl,
        blazeNetApiUrl: apiConfMap[env+'Conf'].blazeNetApiUrl,
        motoApiUrl : apiConfMap[env+'Conf'].motoApiUrl,
        MCPAPIUrl: apiConfMap[env+'Conf'].MCPAPIUrl,
        dpApiUrl:apiConfMap[env+'Conf'].dpApiUrl,
        adminUrl: apiConfMap[env + 'Conf'].adminUrl
    }, configObj)
    return Object.assign({}, configMap);
};

const getConfig = () => {
    return Object.assign({}, configMap);
};

const getParameterByName = (name, url) => {
    if (!url) url = window.location.href;
    url = url.toLowerCase(); // This is just to avoid case sensitiveness
    name = name.replace(/[\[\]]/g, "\\$&").toLowerCase();// This is just to avoid case sensitiveness for query parameter name
    let regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
        results = regex.exec(url);
    if (!results) return null;
    if (!results[2]) return '';
    return decodeURIComponent(results[2].replace(/\+/g, " "));
};

function getDeviceType() {
    let device = "WEB"; //initiate as web
    // device detection
    if (/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|ipad|iris|kindle|Android|Silk|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i.test(navigator.userAgent) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(navigator.userAgent.substr(0, 4))) {
        device = "MOBILE";
    }
    else {
        device = "DESKTOP";
    }
    return device;
}

const init = () => {
    validate.validators.keysCheck = keysCheck;
    validate.validators.cardDate = cardDate;
    validate.validators.cardCheck = cardCheck;
    validate.validators.blazeCardCheck = blazeCardCheck;
    validate.validators.custFormat = custFormat;
    let deviceType = getDeviceType();
    setConfig({deviceType});
    let responded = false;
    setConfig({responded});
    let page = "CJS";
    setConfig({page});

    //for back button cancellation scenario

    if (history && history.pushState) {
        if (getParameterByName('fromBank') === 'yes') {
            //console.log('for cancellation API ==> from bank! ', localStorage.getItem('blazeCardcancelRequestObj'));
            let urlWithQS = window.location.href;
            urlWithQS = urlWithQS.replace('&fromBank=yes', '');
            urlWithQS = urlWithQS.replace('fromBank=yes&', '');
            urlWithQS = urlWithQS.replace('?fromBank=yes', '');
            window.history.pushState({path: urlWithQS}, '', urlWithQS);
        }else {
        //console.log('for cancellation API ==> not from bank!');
        }
    }
};

export {init, handlersMap, configMap, setConfig, getConfig};<|endoftext|>


<commit_before>module.exports = {
    "my_variable_name": {
        "prompt": "please enter a variable for the app name"
    },
    "application_name": {
        "prompt": "what's the name of the application?"
    }
};
<commit_msg>default value<commit_after>module.exports = {
    "my_variable_name": {
        "prompt": "please enter a variable for the app name",
        "defaultValue": "123"
    },
    "application_name": {
        "prompt": "what's the name of the application?"
    }
};
<|endoftext|>


<commit_before>// common.js

$(document).ready(function () {
    // fix menu when passed
    $('.masthead').visibility({
        once: false,
        onBottomPassed: function () {
            $('.fixed.menu').transition('fade in');
        },
        onBottomPassedReverse: function () {
            $('.fixed.menu').transition('fade out');
        }
    });
    // create sidebar and attach to menu open
    $('.ui.sidebar').sidebar('attach events', '.toc.item');
});

// loading dimmer
$('.loading-trigger').click(function () {
    $('#loading-dimmer').dimmer('show');
});

// masthead background
$('.ui.inverted.masthead.segment').addClass('bg' + Math.ceil(Math.random() * 14)).removeClass('zoomed');<commit_msg>Update<commit_after>// common.js

$(document).ready(function () {
    if ($(window).width() >= 768) {
        // fix menu when passed
        $('.masthead').visibility({
            once: false,
            onBottomPassed: function () {
                $('.fixed.menu').transition('fade in');
            },
            onBottomPassedReverse: function () {
                $('.fixed.menu').transition('fade out');
            }
        });
    } else {
        // create sidebar and attach to menu open
        $('.ui.sidebar').sidebar('attach events', '.toc.item');
    };
});

// loading dimmer
$('.loading-trigger').click(function () {
    $('#loading-dimmer').dimmer('show');
});

// masthead background
$('.ui.inverted.masthead.segment').addClass('bg' + Math.ceil(Math.random() * 14)).removeClass('zoomed');<|endoftext|>


<commit_before>
/*!
 * Module dependencies
 */
// native modules
var crypto = require('crypto');

// 3rd party modules
var mongoose = require('mongoose');
var QueryPlugin = require('mongoose-query');

function checksum (str, algorithm, encoding) {
    return crypto
        .createHash(algorithm || 'sha1')
        .update(str, 'binary')
        .digest(encoding || 'hex')
}

var Schema = mongoose.Schema;

/**
 * Location schema
 */
var Location = new Schema({
  url: {type: String }, // fs://... or http://... or ftp://... or sft://...
  auth: {
    usr: { type: String },
    pwd: { type: String }
  }
});

/**
 * Issue schema
 */
var Issue = new Schema({
  time: {type: Date, default: Date.now},
  type: { type: String, enum: ['github', 'jira'] },
  url: { type: String }
});

/**
 * Build schema
 */
var BuildSchema = new Schema({
  name: {type: String, required: true },
  type: { type: String, enum: ['app', 'lib'], default: 'app'},
  cre: {
    user: {type: String},
    time: {type: Date, default: Date.now}
  },
  mod: {
    user: {type: String},
    time: {type: Date, default: Date.now}
  },
  uuid: { type: String },
  vcs: [
    new Schema({
      name: { type: String },
      system: { type: String, enum: ['git','SVN', 'CSV'], default: 'git' },
      type: {type: String, enum: ['PR']},

      commitId: { type: String },
      branch: { type: String },

      base_branch: {type: String},
      base_commit: {type: String},
      pr_number: {type: String},
      url: { type: String },
      clean_wa: { type: Boolean }
    })
  ],
  ci: {
    system: {type: String, enum: ['Jenkins']},
    location: Location,
    job: {
      name: {type: String},
      number: {type: String}
    }
  },
  compiledBy: { type: String, enum: ['CI', 'manual'] },
  changeId: {type: String}, // e.g. when gerrit build
  meta_info: {
    compiler: {type: String},
    version: {type: String},
    toolchain: {type: String},
    machine: {type: String}
  },
  memory: {
    size: {
      heap: {type: Number},
      static_ram: {type: Number},
      total_flash: {type: Number},
      stack: {type: Number},
      total_ram: {type: Number}
    }
  },
  file: {
    //buffer limit 16MB when attached to document!
    name: { type: String },
    data: { type: Buffer },
    size: { type: Number },
    sha1: { type: String },
    sha256: { type: String }
  },
  location: [ Location ],
  issues: [ Issue ],
  // build target device
  target: {
    type: { type: String, enum: ['simulate','hardware'], default: 'hardware'},
    os: { type: String, enum: ['win32', 'win64', 'unix32', 'unix64', 'mbedOS', 'unknown'] },
    simulator: {
      bt: { type: String },
      network: { type: String }
    },
    hw: {
      vendor: { type: String },
      model: {type: String},
      rev: { type: String },
      meta: { type: String }
    }
  }
});

/**
 * Build plugin
 */
BuildSchema.plugin( QueryPlugin ); //install QueryPlugin

/**
 * Add your
 * - pre-save hooks
 * - validations
 * - virtuals
 */

/*
BuildSchema.path('location').validate(function (value, respond) {
    if( value.length === 0 ) respond(false);
    else  respond(true);
 }, '{PATH} missing');
 */

BuildSchema.pre('validate', true, function (next, done) {

  if( this.build && this.build.data ) {
    this.build.size = this.build.data.length;
    this.build.sha1 = checksum(this.build.data, 'sha1');
    this.build.sha256 = checksum(this.build.data, 'sha256');
  }
  if( this.target.type === 'simulate' ){
    if( this.target.simulator ) next();
    else next('simulator missing');
  } else if( this.target.type === 'hardware' ){
    if( this.target.hw ) next();
    else next( 'target missing' );
  } else {
    next( 'target missing' );
  }
 }, '{PATH}: invalid');

/**
 * Methods
 */
//BuildSchema.method({});

/**
 * Statics
 */
//BuildSchema.static({});

/**
 * Register
 */
mongoose.model('Build', BuildSchema);
<commit_msg>Update build.js (#15)<commit_after>
/*!
 * Module dependencies
 */
// native modules
var crypto = require('crypto');

// 3rd party modules
var _ = require('underscore');
var uuid = require('node-uuid');
var mongoose = require('mongoose');
var QueryPlugin = require('mongoose-query');

function checksum (str, algorithm, encoding) {
    return crypto
        .createHash(algorithm || 'sha1')
        .update(str, 'binary')
        .digest(encoding || 'hex')
}

var Schema = mongoose.Schema;

/**
 * Location schema
 */
var Location = new Schema({
  url: {type: String }, // fs://... or http://... or ftp://... or sft://...
  auth: {
    usr: { type: String },
    pwd: { type: String }
  }
});

/**
 * Issue schema
 */
var Issue = new Schema({
  time: {type: Date, default: Date.now},
  type: { type: String, enum: ['github', 'jira'] },
  url: { type: String }
});

/**
 * Build schema
 */
var BuildSchema = new Schema({
  name: {type: String, required: true },
  type: { type: String, enum: ['app', 'lib'], default: 'app'},
  cre: {
    user: {type: String},
    time: {type: Date, default: Date.now}
  },
  mod: {
    user: {type: String},
    time: {type: Date, default: Date.now}
  },
  uuid: { type: String, default: uuid.v4, index: true },
  vcs: [
    new Schema({
      name: { type: String }, //e.g. "github"
      system: { type: String, enum: ['git','SVN', 'CSV'], default: 'git' },
      type: {type: String, enum: ['PR']},

      commitId: { type: String },
      branch: { type: String },

      base_branch: {type: String},
      base_commit: {type: String},
      pr_number: {type: String},
      url: { type: String },
      clean_wa: { type: Boolean }
    })
  ],
  ci: {
    system: {type: String, enum: ['Jenkins', 'travisCI', 'circleCI']},
    location: Location,
    job: {
      name: {type: String},
      number: {type: String}
    }
  },
  compiledBy: { type: String, enum: ['CI', 'manual'] },
  changeId: {type: String}, // e.g. when gerrit build
  meta_info: {
    compiler: {type: String},
    version: {type: String},
    toolchain: {type: String},
    machine: {type: String}
  },
  memory: {
    summary: {
      heap: {type: Number},
      static_ram: {type: Number},
      total_flash: {type: Number},
      stack: {type: Number},
      total_ram: {type: Number}
    }
  },
  files: [{
    //buffer limit 16MB when attached to document!
    name: { type: String },
    mime_type: { type: String },
    data: { type: Buffer },
    size: { type: Number },
    sha1: { type: String },
    sha256: { type: String }
  }],
  issues: [ Issue ],
  // build target device
  target: {
    type: { type: String, enum: ['simulate','hardware'], default: 'hardware', required: true},
    os: { type: String, enum: ['win32', 'win64', 'unix32', 'unix64', 'mbedOS', 'unknown'] },
    simulator: {
      bt: { type: String },
      network: { type: String }
    },
    hw: {
      vendor: { type: String },
      model: {type: String},
      rev: { type: String },
      meta: { type: String }
    }
  }
});

/**
 * Build plugin
 */
BuildSchema.plugin( QueryPlugin ); //install QueryPlugin

/**
 * Add your
 * - pre-save hooks
 * - validations
 * - virtuals
 */

/*
BuildSchema.path('location').validate(function (value, respond) {
    if( value.length === 0 ) respond(false);
    else  respond(true);
 }, '{PATH} missing');
 */

BuildSchema.pre('validate', function (next) {
  var err;
  if( _.isArray(this.files) ) {
    for(i=0;i<this.files.length;i++) {
        var file = this.files[i];
        if( !file.name) {
            err = new Error('file['+i+'].name missing');
            break;
        }
        if(file.data) {
          file.size = file.data.length;
          //file.type = mimetype(file.name(
          file.sha1 = checksum(file.data, 'sha1');
          file.sha256 = checksum(file.data, 'sha256');
        }
    }
  }
  if( err ) {
      return next(err);
  }
  if( this.target.type === 'simulate' ){
    if( !this.target.simulator )
        err = new Error('simulator missing');
  } else if( this.target.type === 'hardware' ){
    if( !this.target.hw )
        err = new Error('target.hw missing');
    else if(!this.target.hw.model)
        err = new Error('target.hw.model missing');
  }
  next(err);
 });

/**
 * Methods
 */
//BuildSchema.method({});

/**
 * Statics
 */
//BuildSchema.static({});

/**
 * Register
 */
mongoose.model('Build', BuildSchema);
<|endoftext|>


<commit_before>Game.Crates = {};

Game.Crates = {
  init: function() {
    this.colors = Game.Crates.colors.randomize();
    this.crates = Game.Crates.types.randomize();
  },
  random: function(limit) {
    limit = limit || this.crates.length - 1;
    return Math.floor(ROT.RNG.getUniform() * limit);
  },
  getTile: function(index) {
    if (this.crates[index].known) {
      return this.crates[index].tile;
    } else {
      return "crate_unknown";
    }
  },
  getColor: function(index) {
    return this.colors[index];
  },
  identify: function(index) {
    this.crates[index].known = true;
  },
  doAction: function(index, x, y, map) {
    this.crates[index].action.call(null, x, y, map, index);
  }
};

Game.Crates.colors = [
0xC2C3C7,
0xFFA300,
0x29ADFF,
0xFF004D,
0x00E756,
];

Game.Crates.actions = {};

Game.Crates.actions.createDecoy = function(x, y, map, crateId) {
  var decoy = Object.create(Game.Entity).init(Game.Entity.templates.decoy, x, y);
  map.addEntity(decoy);
  map.targets.push(decoy);
};

Game.Crates.actions.createDigCrate = function(x, y, map, crateId) {
  var digCrate = Object.create(Game.Entity).init(Game.Entity.templates.digCrate, x, y);
  digCrate.color = Game.Crates.getColor(crateId);
  map.addEntity(digCrate);
  digCrate.falling = 2;
  digCrate.act();
};

Game.Crates.actions.createEnemy = function(x, y, map, crateId) {
  var enemy = Object.create(Game.Entity).init(Game.Entity.templates.skullbot, x, y);
  map.addEntity(enemy);
};

Game.Crates.actions.explode = function(x, y, map, crateId) {
  var blastZone = [{x: x - 1, y: y - 1}, {x: x, y: y - 1}, {x: x + 1, y: y - 1},
                   {x: x - 1, y: y},     {x: x, y: y},     {x: x + 1, y: y},
                   {x: x - 1, y: y + 1}, {x: x, y: y + 1}, {x: x + 1, y: y + 1}];
  console.log('BOOM');
  function blastCell(pos) {
    Game.Screen.addEffect("boom", pos, 0xffffff, 300);
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      var target = map.entityAt(cell.x, cell.y);
      if (target) {
        target.kill({tile:'explosion', niceToBots: false});
      }
      cell.blasted = true;
      cell.neighbors().forEach(function(neighbor){ //link to blasted neigbors
        if (neighbor.blasted && !cell.linked(neighbor)) {
          cell.link(neighbor);
        }
      });
    }
  }
  function cleanUp(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      cell.blasted = undefined;
    }
  }
  blastZone.forEach(blastCell);
  Game.display.render(Game.stage);
  blastZone.forEach(cleanUp);
};

Game.Crates.actions.laserBlast = function(x, y, map, crateId) {
  var blastZone = [                   {x: x, y: y - 2},
                                      {x: x, y: y - 1},
  {x: x - 2, y: y}, {x: x - 1, y: y}, {x: x, y: y}, {x: x + 1, y: y}, {x: x + 2, y: y},
                                      {x: x, y: y + 1},
                                      {x: x, y: y + 2}];
  var zapcolor = 0xffffff;
  var zapduration = 300;
  Game.Screen.addEffect("laser_top", blastZone[0], zapcolor, zapduration);
  Game.Screen.addEffect("laser_vertical", blastZone[1], zapcolor, zapduration);
  Game.Screen.addEffect("laser_left", blastZone[2], zapcolor, zapduration);
  Game.Screen.addEffect("laser_horizontal", blastZone[3], zapcolor, zapduration);
  Game.Screen.addEffect("laser_center", blastZone[4], zapcolor, zapduration);
  Game.Screen.addEffect("laser_horizontal", blastZone[5], zapcolor, zapduration);
  Game.Screen.addEffect("laser_right", blastZone[6], zapcolor, zapduration);
  Game.Screen.addEffect("laser_vertical", blastZone[7], zapcolor, zapduration);
  Game.Screen.addEffect("laser_bottom", blastZone[8], zapcolor, zapduration);
  function blastCell(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      var target = map.entityAt(cell.x, cell.y);
      if (target) {
        target.kill('explosion');
      }
      cell.blasted = true;
      cell.neighbors().forEach(function(neighbor){ //link to blasted neigbors
        if (neighbor.blasted && !cell.linked(neighbor)) {
          cell.link(neighbor);
        }
      });
    }
  }
  function cleanUp(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      cell.blasted = undefined;
    }
  }
  blastZone.forEach(blastCell);
  Game.display.render(Game.stage);
  blastZone.forEach(cleanUp);
};

Game.Crates.types = [
  {
    name: "decoy",
    known: false,
    tile: "crate_decoy",
    action: Game.Crates.actions.createDecoy
  },{
    name: "exploding",
    known: false,
    tile: "crate_blast",
    action: Game.Crates.actions.explode
  },{
    name: "enemy",
    known: false,
    tile: "crate_enemy",
    action: Game.Crates.actions.createEnemy
  },{
    name: "laser",
    known: false,
    tile: "crate_cross",
    action: Game.Crates.actions.laserBlast
  },{
    name: "dig",
    known: false,
    tile: "crate_fall",
    action: Game.Crates.actions.createDigCrate
  }
];
<commit_msg>Fix laserblast explosion<commit_after>Game.Crates = {};

Game.Crates = {
  init: function() {
    this.colors = Game.Crates.colors.randomize();
    this.crates = Game.Crates.types.randomize();
  },
  random: function(limit) {
    limit = limit || this.crates.length - 1;
    return Math.floor(ROT.RNG.getUniform() * limit);
  },
  getTile: function(index) {
    if (this.crates[index].known) {
      return this.crates[index].tile;
    } else {
      return "crate_unknown";
    }
  },
  getColor: function(index) {
    return this.colors[index];
  },
  identify: function(index) {
    this.crates[index].known = true;
  },
  doAction: function(index, x, y, map) {
    this.crates[index].action.call(null, x, y, map, index);
  }
};

Game.Crates.colors = [
0xC2C3C7,
0xFFA300,
0x29ADFF,
0xFF004D,
0x00E756,
];

Game.Crates.actions = {};

Game.Crates.actions.createDecoy = function(x, y, map, crateId) {
  var decoy = Object.create(Game.Entity).init(Game.Entity.templates.decoy, x, y);
  map.addEntity(decoy);
  map.targets.push(decoy);
};

Game.Crates.actions.createDigCrate = function(x, y, map, crateId) {
  var digCrate = Object.create(Game.Entity).init(Game.Entity.templates.digCrate, x, y);
  digCrate.color = Game.Crates.getColor(crateId);
  map.addEntity(digCrate);
  digCrate.falling = 2;
  digCrate.act();
};

Game.Crates.actions.createEnemy = function(x, y, map, crateId) {
  var enemy = Object.create(Game.Entity).init(Game.Entity.templates.skullbot, x, y);
  map.addEntity(enemy);
};

Game.Crates.actions.explode = function(x, y, map, crateId) {
  var blastZone = [{x: x - 1, y: y - 1}, {x: x, y: y - 1}, {x: x + 1, y: y - 1},
                   {x: x - 1, y: y},     {x: x, y: y},     {x: x + 1, y: y},
                   {x: x - 1, y: y + 1}, {x: x, y: y + 1}, {x: x + 1, y: y + 1}];
  console.log('BOOM');
  function blastCell(pos) {
    Game.Screen.addEffect("boom", pos, 0xffffff, 300);
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      var target = map.entityAt(cell.x, cell.y);
      if (target) {
        target.kill({tile:'explosion', niceToBots: false});
      }
      cell.blasted = true;
      cell.neighbors().forEach(function(neighbor){ //link to blasted neigbors
        if (neighbor.blasted && !cell.linked(neighbor)) {
          cell.link(neighbor);
        }
      });
    }
  }
  function cleanUp(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      cell.blasted = undefined;
    }
  }
  blastZone.forEach(blastCell);
  Game.display.render(Game.stage);
  blastZone.forEach(cleanUp);
};

Game.Crates.actions.laserBlast = function(x, y, map, crateId) {
  var blastZone = [                   {x: x, y: y - 2},
                                      {x: x, y: y - 1},
  {x: x - 2, y: y}, {x: x - 1, y: y}, {x: x, y: y}, {x: x + 1, y: y}, {x: x + 2, y: y},
                                      {x: x, y: y + 1},
                                      {x: x, y: y + 2}];
  var zapcolor = 0xffffff;
  var zapduration = 300;
  Game.Screen.addEffect("laser_top", blastZone[0], zapcolor, zapduration);
  Game.Screen.addEffect("laser_vertical", blastZone[1], zapcolor, zapduration);
  Game.Screen.addEffect("laser_left", blastZone[2], zapcolor, zapduration);
  Game.Screen.addEffect("laser_horizontal", blastZone[3], zapcolor, zapduration);
  Game.Screen.addEffect("laser_center", blastZone[4], zapcolor, zapduration);
  Game.Screen.addEffect("laser_horizontal", blastZone[5], zapcolor, zapduration);
  Game.Screen.addEffect("laser_right", blastZone[6], zapcolor, zapduration);
  Game.Screen.addEffect("laser_vertical", blastZone[7], zapcolor, zapduration);
  Game.Screen.addEffect("laser_bottom", blastZone[8], zapcolor, zapduration);
  function blastCell(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      var target = map.entityAt(cell.x, cell.y);
      if (target) {
        target.kill({tile:'explosion', niceToBots: false});
      }
      cell.blasted = true;
      cell.neighbors().forEach(function(neighbor){ //link to blasted neigbors
        if (neighbor.blasted && !cell.linked(neighbor)) {
          cell.link(neighbor);
        }
      });
    }
  }
  function cleanUp(pos) {
    var cell = map.grid.getCell(pos.x, pos.y);
    if (cell) {
      cell.blasted = undefined;
    }
  }
  blastZone.forEach(blastCell);
  Game.display.render(Game.stage);
  blastZone.forEach(cleanUp);
};

Game.Crates.types = [
  {
    name: "decoy",
    known: false,
    tile: "crate_decoy",
    action: Game.Crates.actions.createDecoy
  },{
    name: "exploding",
    known: false,
    tile: "crate_blast",
    action: Game.Crates.actions.explode
  },{
    name: "enemy",
    known: false,
    tile: "crate_enemy",
    action: Game.Crates.actions.createEnemy
  },{
    name: "laser",
    known: false,
    tile: "crate_cross",
    action: Game.Crates.actions.laserBlast
  },{
    name: "dig",
    known: false,
    tile: "crate_fall",
    action: Game.Crates.actions.createDigCrate
  }
];
<|endoftext|>