function (newHeight, widowLayoutStyle) {

		var itemWidthSum = this.left,
			rowWidthWithoutSpacing = this.width - (this.items.length - 1) * this.spacing,
			clampedToNativeRatio,
			clampedHeight,
			errorWidthPerItem,
			roundedCumulativeErrors,
			singleItemGeometry,
			centerOffset;

		// Justify unless explicitly specified otherwise.
		if (typeof widowLayoutStyle === 'undefined' || ['justify', 'center', 'left'].indexOf(widowLayoutStyle) < 0) {
			widowLayoutStyle = 'left';
		}

		// Clamp row height to edge case minimum/maximum.
		clampedHeight = Math.max(this.edgeCaseMinRowHeight, Math.min(newHeight, this.edgeCaseMaxRowHeight));

		if (newHeight !== clampedHeight) {

			// If row height was clamped, the resulting row/item aspect ratio will be off,
			// so force it to fit the width (recalculate aspectRatio to match clamped height).
			// NOTE: this will result in cropping/padding commensurate to the amount of clamping.
			this.height = clampedHeight;
			clampedToNativeRatio = (rowWidthWithoutSpacing / clampedHeight) / (rowWidthWithoutSpacing / newHeight);

		} else {

			// If not clamped, leave ratio at 1.0.
			this.height = newHeight;
			clampedToNativeRatio = 1.0;

		}

		// Compute item geometry based on newHeight.
		this.items.forEach(function (item) {

			item.top = this.top;
			item.width = item.aspectRatio * this.height * clampedToNativeRatio;
			item.height = this.height;

			// Left-to-right.
			// TODO right to left
			// item.left = this.width - itemWidthSum - item.width;
			item.left = itemWidthSum;

			// Increment width.
			itemWidthSum += item.width + this.spacing;

		}, this);

		// If specified, ensure items fill row and distribute error
		// caused by rounding width and height across all items.
		if (widowLayoutStyle === 'justify') {

			itemWidthSum -= (this.spacing + this.left);

			errorWidthPerItem = (itemWidthSum - this.width) / this.items.length;
			roundedCumulativeErrors = this.items.map(function (item, i) {
				return Math.round((i + 1) * errorWidthPerItem);
			});

			if (this.items.length === 1) {

				// For rows with only one item, adjust item width to fill row.
				singleItemGeometry = this.items[0];
				singleItemGeometry.width -= Math.round(errorWidthPerItem);

			} else {

				// For rows with multiple items, adjust item width and shift items to fill the row,
				// while maintaining equal spacing between items in the row.
				this.items.forEach(function (item, i) {
					if (i > 0) {
						item.left -= roundedCumulativeErrors[i - 1];
						item.width -= (roundedCumulativeErrors[i] - roundedCumulativeErrors[i - 1]);
					} else {
						item.width -= roundedCumulativeErrors[i];
					}
				});

			}

		} else if (widowLayoutStyle === 'center') {

			// Center widows
			centerOffset = (this.width - itemWidthSum) / 2;

			this.items.forEach(function (item) {
				item.left += centerOffset + this.spacing;
			}, this);

		}

	}

Set row height and compute item geometry from that height.
Will justify items within the row unless instructed not to.

@method completeLayout
@param newHeight {Number} Set row height to this value.
@param widowLayoutStyle {String} How should widows display? Supported: left | justify | center

Set row height and compute item geometry from that height . Will justify items within the row unless instructed not to .


function createNewRow(layoutConfig, layoutData) {

	var isBreakoutRow;

	// Work out if this is a full width breakout row
	if (layoutConfig.fullWidthBreakoutRowCadence !== false) {
		if (((layoutData._rows.length + 1) % layoutConfig.fullWidthBreakoutRowCadence) === 0) {
			isBreakoutRow = true;
		}
	}

	return new Row({
		top: layoutData._containerHeight,
		left: layoutConfig.containerPadding.left,
		width: layoutConfig.containerWidth - layoutConfig.containerPadding.left - layoutConfig.containerPadding.right,
		spacing: layoutConfig.boxSpacing.horizontal,
		targetRowHeight: layoutConfig.targetRowHeight,
		targetRowHeightTolerance: layoutConfig.targetRowHeightTolerance,
		edgeCaseMinRowHeight: 0.5 * layoutConfig.targetRowHeight,
		edgeCaseMaxRowHeight: 2 * layoutConfig.targetRowHeight,
		rightToLeft: false,
		isBreakoutRow: isBreakoutRow,
		widowLayoutStyle: layoutConfig.widowLayoutStyle
	});
}

Create a new, empty row.

@method createNewRow
@param layoutConfig {Object} The layout configuration
@param layoutData {Object} The current state of the layout
@return A new, empty row of the type specified by this layout.


function (path, strategy) {
    if (typeof path !== 'string') {
      throw new Error('path should be a string');
    }
    if (!util.isFolder(path)) {
      throw new Error('path should be a folder');
    }
    if (this._remoteStorage && this._remoteStorage.access &&
        !this._remoteStorage.access.checkPathPermission(path, 'r')) {
      throw new Error('No access to path "'+path+'". You have to claim access to it first.');
    }
    if (!strategy.match(/^(FLUSH|SEEN|ALL)$/)) {
      throw new Error("strategy should be 'FLUSH', 'SEEN', or 'ALL'");
    }

    this._rootPaths[path] = strategy;

    if (strategy === 'ALL') {
      if (this.activateHandler) {
        this.activateHandler(path);
      } else {
        this.pendingActivations.push(path);
      }
    }
  }

Configure caching for a given path explicitly.

Not needed when using ``enable``/``disable``.

@param {string} path - Path to cache
@param {string} strategy - Caching strategy. One of 'ALL', 'SEEN', or 'FLUSH'.

Configure caching for a given path explicitly .


function (cb) {
    var i;
    log('[Caching] Setting activate handler', cb, this.pendingActivations);
    this.activateHandler = cb;
    for (i=0; i<this.pendingActivations.length; i++) {
      cb(this.pendingActivations[i]);
    }
    delete this.pendingActivations;
  }

function
(
cb
)
{
var
i
;
log
(
'[Caching] Setting activate handler'
,
cb
,
this
.
pendingActivations
)
;
this
.
activateHandler
=
cb
;
for
(
i
=
0
;
i
<
this
.
pendingActivations
.
length
;
i
++
)
{
cb
(
this
.
pendingActivations
[
i
]
)
;
}
delete
this
.
pendingActivations
;
}

Set a callback for when caching is activated for a path.

@param {function} callback - Callback function

Set a callback for when caching is activated for a path .


function (path) {
    if (this._rootPaths[path] !== undefined) {
      return this._rootPaths[path];
    } else if (path === '/') {
      return 'SEEN';
    } else {
      return this.checkPath(containingFolder(path));
    }
  }

function ( path ) { if ( this . _rootPaths [ path ] !== undefined ) { return this . _rootPaths [ path ] ; } else if ( path === '/' ) { return 'SEEN' ; } else { return this . checkPath ( containingFolder ( path ) ) ; } }

Retrieve caching setting for a given path, or its next parent
with a caching strategy set.

@param {string} path - Path to retrieve setting for
@returns {string} caching strategy for the path

Retrieve caching setting for a given path or its next parent with a caching strategy set .


function(scope, mode) {
    if (typeof(scope) !== 'string' || scope.indexOf('/') !== -1 || scope.length === 0) {
      throw new Error('Scope should be a non-empty string without forward slashes');
    }
    if (!mode.match(/^rw?$/)) {
      throw new Error('Mode should be either \'r\' or \'rw\'');
    }
    this._adjustRootPaths(scope);
    this.scopeModeMap[scope] = mode;
  }

Claim access on a given scope with given mode.

@param {string} scope - An access scope, such as "contacts" or "calendar"
@param {string} mode - Access mode. Either "r" for read-only or "rw" for read/write

Claim access on a given scope with given mode .


function(scope) {
    var savedMap = {};
    var name;
    for (name in this.scopeModeMap) {
      savedMap[name] = this.scopeModeMap[name];
    }
    this.reset();
    delete savedMap[scope];
    for (name in savedMap) {
      this.set(name, savedMap[name]);
    }
  }

function ( scope ) { var savedMap = { } ; var name ; for ( name in this . scopeModeMap ) { savedMap [ name ] = this . scopeModeMap [ name ] ; } this . reset ( ) ; delete savedMap [ scope ] ; for ( name in savedMap ) { this . set ( name , savedMap [ name ] ) ; } }

Remove access for the given scope.

@param {string} scope - Access scope


function metaTitleFromFileName (filename) {
  if (filename.substr(-1) === '/') {
    filename = filename.substr(0, filename.length - 1);
  }

  return decodeURIComponent(filename);
}

function metaTitleFromFileName ( filename ) { if ( filename . substr ( - 1 ) === '/' ) { filename = filename . substr ( 0 , filename . length - 1 ) ; } return decodeURIComponent ( filename ) ; }

Produce a title from a filename for metadata.

@param {string} filename
@returns {string} title

@private

Produce a title from a filename for metadata .


function baseName (path) {
  const parts = path.split('/');
  if (path.substr(-1) === '/') {
    return parts[parts.length-2]+'/';
  } else {
    return parts[parts.length-1];
  }
}

function baseName ( path ) { const parts = path . split ( '/' ) ; if ( path . substr ( - 1 ) === '/' ) { return parts [ parts . length - 2 ] + '/' ; } else { return parts [ parts . length - 1 ] ; } }

Get only the filename from a full path.

@param {string} path
@returns {string} filename

@private

Get only the filename from a full path .


function () {
    this.rs.setBackend('googledrive');
    this.rs.authorize({ authURL: AUTH_URL, scope: AUTH_SCOPE, clientId: this.clientId });
  }

function ( ) { this . rs . setBackend ( 'googledrive' ) ; this . rs . authorize ( { authURL : AUTH_URL , scope : AUTH_SCOPE , clientId : this . clientId } ) ; }

Initiate the authorization flow's OAuth dance.

Initiate the authorization flow s OAuth dance .


function (path, body, contentType, options) {
    const fullPath = googleDrivePath(path);

    function putDone(response) {
      if (response.status >= 200 && response.status < 300) {
        const meta = JSON.parse(response.responseText);
        const etagWithoutQuotes = removeQuotes(meta.etag);
        return Promise.resolve({statusCode: 200, contentType: meta.mimeType, revision: etagWithoutQuotes});
      } else if (response.status === 412) {
        return Promise.resolve({statusCode: 412, revision: 'conflict'});
      } else {
        return Promise.reject("PUT failed with status " + response.status + " (" + response.responseText + ")");
      }
    }

    return this._getFileId(fullPath).then((id) => {
      if (id) {
        if (options && (options.ifNoneMatch === '*')) {
          return putDone({ status: 412 });
        }
        return this._updateFile(id, fullPath, body, contentType, options).then(putDone);
      } else {
        return this._createFile(fullPath, body, contentType, options).then(putDone);
      }
    });
  }

function
(
path
,
body
,
contentType
,
options
)
{
const
fullPath
=
googleDrivePath
(
path
)
;
function
putDone
(
response
)
{
if
(
response
.
status
>=
200
&&
response
.
status
<
300
)
{
const
meta
=
JSON
.
parse
(
response
.
responseText
)
;
const
etagWithoutQuotes
=
removeQuotes
(
meta
.
etag
)
;
return
Promise
.
resolve
(
{
statusCode
:
200
,
contentType
:
meta
.
mimeType
,
revision
:
etagWithoutQuotes
}
)
;
}
else
if
(
response
.
status
===
412
)
{
return
Promise
.
resolve
(
{
statusCode
:
412
,
revision
:
'conflict'
}
)
;
}
else
{
return
Promise
.
reject
(
"PUT failed with status "
+
response
.
status
+
" ("
+
response
.
responseText
+
")"
)
;
}
}
return
this
.
_getFileId
(
fullPath
)
.
then
(
(
id
)
=>
{
if
(
id
)
{
if
(
options
&&
(
options
.
ifNoneMatch
===
'*'
)
)
{
return
putDone
(
{
status
:
412
}
)
;
}
return
this
.
_updateFile
(
id
,
fullPath
,
body
,
contentType
,
options
)
.
then
(
putDone
)
;
}
else
{
return
this
.
_createFile
(
fullPath
,
body
,
contentType
,
options
)
.
then
(
putDone
)
;
}
}
)
;
}

Create or update a file.

@param {string} path - File path
@param body - File content
@param {string} contentType - File content-type
@param {Object} options
@param {string} options.ifNoneMatch - Only create of update the file if the
current ETag doesn't match this string
@returns {Promise} Resolves with an object containing the status code,
content-type and revision

@protected


function (path, options) {
    const fullPath = googleDrivePath(path);

    return this._getFileId(fullPath).then((id) => {
      if (!id) {
        // File doesn't exist. Ignore.
        return Promise.resolve({statusCode: 200});
      }

      return this._getMeta(id).then((meta) => {
        let etagWithoutQuotes;
        if ((typeof meta === 'object') && (typeof meta.etag === 'string')) {
          etagWithoutQuotes = removeQuotes(meta.etag);
        }
        if (options && options.ifMatch && (options.ifMatch !== etagWithoutQuotes)) {
          return {statusCode: 412, revision: etagWithoutQuotes};
        }

        return this._request('DELETE', BASE_URL + '/drive/v2/files/' + id, {}).then((response) => {
          if (response.status === 200 || response.status === 204) {
            return {statusCode: 200};
          } else {
            return Promise.reject("Delete failed: " + response.status + " (" + response.responseText + ")");
          }
        });
      });
    });
  }

function
(
path
,
options
)
{
const
fullPath
=
googleDrivePath
(
path
)
;
return
this
.
_getFileId
(
fullPath
)
.
then
(
(
id
)
=>
{
if
(
!
id
)
{
// File doesn't exist. Ignore.
return
Promise
.
resolve
(
{
statusCode
:
200
}
)
;
}
return
this
.
_getMeta
(
id
)
.
then
(
(
meta
)
=>
{
let
etagWithoutQuotes
;
if
(
(
typeof
meta
===
'object'
)
&&
(
typeof
meta
.
etag
===
'string'
)
)
{
etagWithoutQuotes
=
removeQuotes
(
meta
.
etag
)
;
}
if
(
options
&&
options
.
ifMatch
&&
(
options
.
ifMatch
!==
etagWithoutQuotes
)
)
{
return
{
statusCode
:
412
,
revision
:
etagWithoutQuotes
}
;
}
return
this
.
_request
(
'DELETE'
,
BASE_URL
+
'/drive/v2/files/'
+
id
,
{
}
)
.
then
(
(
response
)
=>
{
if
(
response
.
status
===
200
||
response
.
status
===
204
)
{
return
{
statusCode
:
200
}
;
}
else
{
return
Promise
.
reject
(
"Delete failed: "
+
response
.
status
+
" ("
+
response
.
responseText
+
")"
)
;
}
}
)
;
}
)
;
}
)
;
}

Delete a file.

@param {string} path - File path
@param {Object} options
@param {string} options.ifMatch - only delete the file if it's ETag
matches this string
@returns {Promise} Resolves with an object containing the status code

@protected


function () {
    const url = BASE_URL + '/drive/v2/about?fields=user';
    // requesting user info(mainly for userAdress)
    return this._request('GET', url, {}).then(function (resp){
      try {
        const info = JSON.parse(resp.responseText);
        return Promise.resolve(info);
      } catch (e) {
        return Promise.reject(e);
      }
    });
  }

Fetch the user's info from Google.

@returns {Promise} resolves with the user's info.

@protected


function (id, path, body, contentType, options) {
    const metadata = {
      mimeType: contentType
    };
    const headers = {
      'Content-Type': 'application/json; charset=UTF-8'
    };

    if (options && options.ifMatch) {
      headers['If-Match'] = '"' + options.ifMatch + '"';
    }

    return this._request('PUT', BASE_URL + '/upload/drive/v2/files/' + id + '?uploadType=resumable', {
      body: JSON.stringify(metadata),
      headers: headers
    }).then((response) => {
      if (response.status === 412) {
        return (response);
      } else {
        return this._request('PUT', response.getResponseHeader('Location'), {
          body: contentType.match(/^application\/json/) ? JSON.stringify(body) : body
        });
      }
    });
  }

function
(
id
,
path
,
body
,
contentType
,
options
)
{
const
metadata
=
{
mimeType
:
contentType
}
;
const
headers
=
{
'Content-Type'
:
'application/json; charset=UTF-8'
}
;
if
(
options
&&
options
.
ifMatch
)
{
headers
[
'If-Match'
]
=
'"'
+
options
.
ifMatch
+
'"'
;
}
return
this
.
_request
(
'PUT'
,
BASE_URL
+
'/upload/drive/v2/files/'
+
id
+
'?uploadType=resumable'
,
{
body
:
JSON
.
stringify
(
metadata
)
,
headers
:
headers
}
)
.
then
(
(
response
)
=>
{
if
(
response
.
status
===
412
)
{
return
(
response
)
;
}
else
{
return
this
.
_request
(
'PUT'
,
response
.
getResponseHeader
(
'Location'
)
,
{
body
:
contentType
.
match
(
/
^application\/json
/
)
JSON
.
stringify
(
body
)
:
body
}
)
;
}
}
)
;
}

Update an existing file.

@param {string} id - File ID
@param {string} path - File path
@param body - File content
@param {string} contentType - File content-type
@param {Object} options
@param {string} options.ifMatch - Only update the file if its ETag
matches this string
@returns {Promise} Resolves with the response of the network request

@private


function (path, body, contentType/*, options*/) {
    return this._getParentId(path).then((parentId) => {
      const fileName = baseName(path);
      const metadata = {
        title: metaTitleFromFileName(fileName),
        mimeType: contentType,
        parents: [{
          kind: "drive#fileLink",
          id: parentId
        }]
      };
      return this._request('POST', BASE_URL + '/upload/drive/v2/files?uploadType=resumable', {
        body: JSON.stringify(metadata),
        headers: {
          'Content-Type': 'application/json; charset=UTF-8'
        }
      }).then((response) => {
        return this._request('POST', response.getResponseHeader('Location'), {
          body: contentType.match(/^application\/json/) ? JSON.stringify(body) : body
        });
      });
    });
  }

Create a new file.

@param {string} path - File path
@param body - File content
@param {string} contentType - File content-type
@returns {Promise} Resolves with the response of the network request

@private


function (path, options) {
    return this._getFileId(path).then((id) => {
      return this._getMeta(id).then((meta) => {
        let etagWithoutQuotes;
        if (typeof(meta) === 'object' && typeof(meta.etag) === 'string') {
          etagWithoutQuotes = removeQuotes(meta.etag);
        }

        if (options && options.ifNoneMatch && (etagWithoutQuotes === options.ifNoneMatch)) {
          return Promise.resolve({statusCode: 304});
        }

        if (!meta.downloadUrl) {
          if (meta.exportLinks && meta.exportLinks['text/html']) {
            // Documents that were generated inside GoogleDocs have no
            // downloadUrl, but you can export them to text/html instead:
            meta.mimeType += ';export=text/html';
            meta.downloadUrl = meta.exportLinks['text/html'];
          } else {
            // empty file
            return Promise.resolve({statusCode: 200, body: '', contentType: meta.mimeType, revision: etagWithoutQuotes});
          }
        }

        var params = {
          responseType: 'arraybuffer'
        };
        return this._request('GET', meta.downloadUrl, params).then((response) => {
          //first encode the response as text, and later check if
          //text appears to actually be binary data
          return getTextFromArrayBuffer(response.response, 'UTF-8').then(function (responseText) {
            let body = responseText;
            if (meta.mimeType.match(/^application\/json/)) {
              try {
                body = JSON.parse(body);
              } catch(e) {
                // body couldn't be parsed as JSON, so we'll just return it as is
              }
            } else {
              if (shouldBeTreatedAsBinary(responseText, meta.mimeType)) {
                //return unprocessed response
                body = response.response;
              }
            }

            return {statusCode: 200, body: body, contentType: meta.mimeType, revision: etagWithoutQuotes};
          });
        });
      });
    });
  }

Request a file.

@param {string} path - File path
@param {Object} options
@param {string} [options.ifNoneMath] - Only return the file if its ETag
doesn't match the given string
@returns {Promise} Resolves with an object containing the status code,
body, content-type and revision

@private


function (path/*, options*/) {
    return this._getFileId(path).then((id) => {
      let query, fields, data, etagWithoutQuotes, itemsMap;
      if (! id) {
        return Promise.resolve({statusCode: 404});
      }

      query = '\'' + id + '\' in parents';
      fields = 'items(downloadUrl,etag,fileSize,id,mimeType,title)';
      return this._request('GET', BASE_URL + '/drive/v2/files?'
          + 'q=' + encodeURIComponent(query)
          + '&fields=' + encodeURIComponent(fields)
          + '&maxResults=1000',
          {})
      .then((response) => {
        if (response.status !== 200) {
          return Promise.reject('request failed or something: ' + response.status);
        }

        try {
          data = JSON.parse(response.responseText);
        } catch(e) {
          return Promise.reject('non-JSON response from GoogleDrive');
        }

        itemsMap = {};
        for (const item of data.items) {
          etagWithoutQuotes = removeQuotes(item.etag);
          if (item.mimeType === GD_DIR_MIME_TYPE) {
            this._fileIdCache.set(path + item.title + '/', item.id);
            itemsMap[item.title + '/'] = {
              ETag: etagWithoutQuotes
            };
          } else {
            this._fileIdCache.set(path + item.title, item.id);
            itemsMap[item.title] = {
              ETag: etagWithoutQuotes,
              'Content-Type': item.mimeType,
              'Content-Length': item.fileSize
            };
          }
        }

        // FIXME: add revision of folder!
        return Promise.resolve({statusCode: 200, body: itemsMap, contentType: RS_DIR_MIME_TYPE, revision: undefined});
      });
    });
  }

Request a directory.

@param {string} path - Directory path
@param {Object} options
@returns {Promise} Resolves with an object containing the status code,
body and content-type

@private


function (path) {
    const foldername = parentPath(path);

    return this._getFileId(foldername).then((parentId) => {
      if (parentId) {
        return Promise.resolve(parentId);
      } else {
        return this._createFolder(foldername);
      }
    });
  }

function ( path ) { const foldername = parentPath ( path ) ; return this . _getFileId ( foldername ) . then ( ( parentId ) => { if ( parentId ) { return Promise . resolve ( parentId ) ; } else { return this . _createFolder ( foldername ) ; } } ) ; }

Get the ID of a parent path.

Creates the directory if it doesn't exist yet.

@param {string} path - Full path of a directory or file
@returns {Promise} Resolves with ID of the parent directory.

@private


function (path) {
    return this._getParentId(path).then((parentId) => {
      return this._request('POST', BASE_URL + '/drive/v2/files', {
        body: JSON.stringify({
          title: metaTitleFromFileName(baseName(path)),
          mimeType: GD_DIR_MIME_TYPE,
          parents: [{
            id: parentId
          }]
        }),
        headers: {
          'Content-Type': 'application/json; charset=UTF-8'
        }
      }).then((response) => {
        const meta = JSON.parse(response.responseText);
        return Promise.resolve(meta.id);
      });
    });
  }

function
(
path
)
{
return
this
.
_getParentId
(
path
)
.
then
(
(
parentId
)
=>
{
return
this
.
_request
(
'POST'
,
BASE_URL
+
'/drive/v2/files'
,
{
body
:
JSON
.
stringify
(
{
title
:
metaTitleFromFileName
(
baseName
(
path
)
)
,
mimeType
:
GD_DIR_MIME_TYPE
,
parents
:
[
{
id
:
parentId
}
]
}
)
,
headers
:
{
'Content-Type'
:
'application/json; charset=UTF-8'
}
}
)
.
then
(
(
response
)
=>
{
const
meta
=
JSON
.
parse
(
response
.
responseText
)
;
return
Promise
.
resolve
(
meta
.
id
)
;
}
)
;
}
)
;
}

Create a directory.

Creates all parent directories as well if any of them didn't exist yet.

@param {string} path - Directory path
@returns {Promise} Resolves with the ID of the new directory

@private


function (path) {
    let id;

    if (path === '/') {
      // "root" is a special alias for the fileId of the root folder
      return Promise.resolve('root');
    } else if ((id = this._fileIdCache.get(path))) {
      // id is cached.
      return Promise.resolve(id);
    }
    // id is not cached (or file doesn't exist).
    // load parent folder listing to propagate / update id cache.
    return this._getFolder(parentPath(path)).then(() => {
      id = this._fileIdCache.get(path);
      if (!id) {
        if (path.substr(-1) === '/') {
          return this._createFolder(path).then(() => {
            return this._getFileId(path);
          });
        } else {
          return Promise.resolve();
        }
      }
      return Promise.resolve(id);
    });
  }

Get the ID of a file.

@param {string} path - File path
@returns {Promise} Resolves with the ID

@private


function (id) {
    return this._request('GET', BASE_URL + '/drive/v2/files/' + id, {}).then(function (response) {
      if (response.status === 200) {
        return Promise.resolve(JSON.parse(response.responseText));
      } else {
        return Promise.reject("request (getting metadata for " + id + ") failed with status: " + response.status);
      }
    });
  }

function
(
id
)
{
return
this
.
_request
(
'GET'
,
BASE_URL
+
'/drive/v2/files/'
+
id
,
{
}
)
.
then
(
function
(
response
)
{
if
(
response
.
status
===
200
)
{
return
Promise
.
resolve
(
JSON
.
parse
(
response
.
responseText
)
)
;
}
else
{
return
Promise
.
reject
(
"request (getting metadata for "
+
id
+
") failed with status: "
+
response
.
status
)
;
}
}
)
;
}

Get the metadata for a given file ID.

@param {string} id - File ID
@returns {Promise} Resolves with an object containing the metadata

@private


function unHookGetItemURL (rs) {
  if (!rs._origBaseClientGetItemURL) { return; }
  BaseClient.prototype.getItemURL = rs._origBaseClientGetItemURL;
  delete rs._origBaseClientGetItemURL;
}

function unHookGetItemURL ( rs ) { if ( ! rs . _origBaseClientGetItemURL ) { return ; } BaseClient . prototype . getItemURL = rs . _origBaseClientGetItemURL ; delete rs . _origBaseClientGetItemURL ; }

Restore BaseClient's getItemURL original implementation

@param {object} rs - RemoteStorage instance

@private

Restore BaseClient s getItemURL original implementation


function (eventName, handler) {
    if (typeof(eventName) !== 'string') {
      throw new Error('Argument eventName should be a string');
    }
    if (typeof(handler) !== 'function') {
      throw new Error('Argument handler should be a function');
    }
    log('[Eventhandling] Adding event listener', eventName);
    this._validateEvent(eventName);
    this._handlers[eventName].push(handler);
  }

function
(
eventName
,
handler
)
{
if
(
typeof
(
eventName
)
!==
'string'
)
{
throw
new
Error
(
'Argument eventName should be a string'
)
;
}
if
(
typeof
(
handler
)
!==
'function'
)
{
throw
new
Error
(
'Argument handler should be a function'
)
;
}
log
(
'[Eventhandling] Adding event listener'
,
eventName
)
;
this
.
_validateEvent
(
eventName
)
;
this
.
_handlers
[
eventName
]
.
push
(
handler
)
;
}

Install an event handler for the given event name


function (eventName, handler) {
    this._validateEvent(eventName);
    var hl = this._handlers[eventName].length;
    for (var i=0;i<hl;i++) {
      if (this._handlers[eventName][i] === handler) {
        this._handlers[eventName].splice(i, 1);
        return;
      }
    }
  }

function ( eventName , handler ) { this . _validateEvent ( eventName ) ; var hl = this . _handlers [ eventName ] . length ; for ( var i = 0 ; i < hl ; i ++ ) { if ( this . _handlers [ eventName ] [ i ] === handler ) { this . _handlers [ eventName ] . splice ( i , 1 ) ; return ; } } }

Remove a previously installed event handler


function Discover(userAddress) {
  return new Promise((resolve, reject) => {

    if (userAddress in cachedInfo) {
      return resolve(cachedInfo[userAddress]);
    }

    var webFinger = new WebFinger({
      tls_only: false,
      uri_fallback: true,
      request_timeout: 5000
    });

    return webFinger.lookup(userAddress, function (err, response) {
      if (err) {
        return reject(err);
      } else if ((typeof response.idx.links.remotestorage !== 'object') ||
                 (typeof response.idx.links.remotestorage.length !== 'number') ||
                 (response.idx.links.remotestorage.length <= 0)) {
        log("[Discover] WebFinger record for " + userAddress + " does not have remotestorage defined in the links section ", JSON.stringify(response.json));
        return reject("WebFinger record for " + userAddress + " does not have remotestorage defined in the links section.");
      }

      var rs = response.idx.links.remotestorage[0];
      var authURL = rs.properties['http://tools.ietf.org/html/rfc6749#section-4.2'] ||
                    rs.properties['auth-endpoint'];
      var storageApi = rs.properties['http://remotestorage.io/spec/version'] ||
                       rs.type;

      // cache fetched data
      cachedInfo[userAddress] = {
        href: rs.href,
        storageApi: storageApi,
        authURL: authURL,
        properties: rs.properties
      };

      if (hasLocalStorage) {
        localStorage[SETTINGS_KEY] = JSON.stringify({ cache: cachedInfo });
      }

      return resolve(cachedInfo[userAddress]);
    });
  });
}

This function deals with the Webfinger lookup, discovering a connecting
user's storage details.

@param {string} userAddress - user@host

@returns {Promise} A promise for an object with the following properties.
href - Storage base URL,
storageApi - RS protocol version,
authUrl - OAuth URL,
properties - Webfinger link properties

This function deals with the Webfinger lookup discovering a connecting user s storage details .


function () {
    // TODO handling when token is already present
    this.rs.setBackend('dropbox');
    if (this.token){
      hookIt(this.rs);
    } else {
      this.rs.authorize({ authURL: AUTH_URL, scope: '', clientId: this.clientId });
    }
  }

Set the backed to 'dropbox' and start the authentication flow in order
to obtain an API token from Dropbox.

Set the backed to dropbox and start the authentication flow in order to obtain an API token from Dropbox .


function (path) {
    var url = 'https://api.dropboxapi.com/2/files/list_folder';
    var revCache = this._revCache;
    var self = this;

    var processResponse = function (resp) {
      var body, listing;

      if (resp.status !== 200 && resp.status !== 409) {
        return Promise.reject('Unexpected response status: ' + resp.status);
      }

      try {
        body = JSON.parse(resp.responseText);
      } catch (e) {
        return Promise.reject(e);
      }

      if (resp.status === 409) {
        if (compareApiError(body, ['path', 'not_found'])) {
          // if the folder is not found, handle it as an empty folder
          return Promise.resolve({});
        }

        return Promise.reject(new Error('API returned an error: ' + body.error_summary));
      }

      listing = body.entries.reduce(function (map, item) {
        var isDir = item['.tag'] === 'folder';
        var itemName = item.path_lower.split('/').slice(-1)[0] + (isDir ? '/' : '');
        if (isDir){
          map[itemName] = { ETag: revCache.get(path+itemName) };
        } else {
          map[itemName] = { ETag: item.rev };
          self._revCache.set(path+itemName, item.rev);
        }
        return map;
      }, {});

      if (body.has_more) {
        return loadNext(body.cursor).then(function (nextListing) {
          return Object.assign(listing, nextListing);
        });
      }

      return Promise.resolve(listing);
    };

    const loadNext = function (cursor) {
      const continueURL = 'https://api.dropboxapi.com/2/files/list_folder/continue';
      const params = {
        body: { cursor: cursor }
      };

      return self._request('POST', continueURL, params).then(processResponse);
    };

    return this._request('POST', url, {
      body: {
        path: getDropboxPath(path)
      }
    }).then(processResponse).then(function (listing) {
      return Promise.resolve({
        statusCode: 200,
        body: listing,
        contentType: 'application/json; charset=UTF-8',
        revision: revCache.get(path)
      });
    });
  }

Get all items in a folder.

@param path {string} - path of the folder to get, with leading slash
@return {Object}
statusCode - HTTP status code
body - array of the items found
contentType - 'application/json; charset=UTF-8'
revision - revision of the folder

@private


function (path, options) {
    if (! this.connected) { return Promise.reject("not connected (path: " + path + ")"); }
    var url = 'https://content.dropboxapi.com/2/files/download';
    var self = this;

    var savedRev = this._revCache.get(path);
    if (savedRev === null) {
      // file was deleted server side
      return Promise.resolve({statusCode: 404});
    }
    if (options && options.ifNoneMatch) {
      // We must wait for local revision cache to be initialized before
      // checking if local revision is outdated
      if (! this._initialFetchDone) {
        return this.fetchDelta().then(() => {
          return this.get(path, options);
        });
      }

      if (savedRev && (savedRev === options.ifNoneMatch)) {
        // nothing changed.
        return Promise.resolve({statusCode: 304});
      }
    }

    //use _getFolder for folders
    if (path.substr(-1) === '/') {
      return this._getFolder(path, options);
    }

    var params = {
      headers: {
        'Dropbox-API-Arg': JSON.stringify({path: getDropboxPath(path)}),
      },
      responseType: 'arraybuffer'
    };
    if (options && options.ifNoneMatch) {
      params.headers['If-None-Match'] = options.ifNoneMatch;
    }

    return this._request('GET', url, params).then(function (resp) {
      var status = resp.status;
      var meta, body, mime, rev;
      if (status !== 200 && status !== 409) {
        return Promise.resolve({statusCode: status});
      }
      meta = resp.getResponseHeader('Dropbox-API-Result');
      //first encode the response as text, and later check if
      //text appears to actually be binary data
      return getTextFromArrayBuffer(resp.response, 'UTF-8').then(function (responseText) {
        body = responseText;
        if (status === 409) {
          meta = body;
        }

        try {
          meta = JSON.parse(meta);
        } catch(e) {
          return Promise.reject(e);
        }

        if (status === 409) {
          if (compareApiError(meta, ['path', 'not_found'])) {
            return {statusCode: 404};
          }
          return Promise.reject(new Error('API error while downloading file ("' + path + '"): ' + meta.error_summary));
        }

        mime = resp.getResponseHeader('Content-Type');
        rev = meta.rev;
        self._revCache.set(path, rev);
        self._shareIfNeeded(path);

        if (shouldBeTreatedAsBinary(responseText, mime)) {
          //return unprocessed response
          body = resp.response;
        } else {
          // handling json (always try)
          try {
            body = JSON.parse(body);
            mime = 'application/json; charset=UTF-8';
          } catch(e) {
            //Failed parsing Json, assume it is something else then
          }
        }

        return {
          statusCode: status,
          body: body,
          contentType: mime,
          revision: rev
        };
      });
    });
  }

Checks for the path in ``_revCache`` and decides based on that if file
has changed. Calls ``_getFolder`` is the path points to a folder.

Calls ``Dropbox.share`` afterwards to fill ``_itemRefs``.

Compatible with ``WireClient.get``

@param path {string} - path of the folder to get, with leading slash
@param options {Object}

@protected

Checks for the path in _revCache and decides based on that if file has changed . Calls _getFolder is the path points to a folder .


function (path) {
    var url = 'https://api.dropboxapi.com/2/sharing/create_shared_link_with_settings';
    var options = {
      body: {path: getDropboxPath(path)}
    };

    return this._request('POST', url, options).then((response) => {
      if (response.status !== 200 && response.status !== 409) {
        return Promise.reject(new Error('Invalid response status:' + response.status));
      }

      var body;

      try {
        body = JSON.parse(response.responseText);
      } catch (e) {
        return Promise.reject(new Error('Invalid response body: ' + response.responseText));
      }

      if (response.status === 409) {
        if (compareApiError(body, ['shared_link_already_exists'])) {
          return this._getSharedLink(path);
        }

        return Promise.reject(new Error('API error: ' + body.error_summary));
      }

      return Promise.resolve(body.url);
    }).then((link) => {
      this._itemRefs[path] = link;

      if (hasLocalStorage) {
        localStorage.setItem(SETTINGS_KEY+':shares', JSON.stringify(this._itemRefs));
      }

      return Promise.resolve(link);
    }, (error) => {
      error.message = 'Sharing Dropbox file or folder ("' + path + '") failed: ' + error.message;
      return Promise.reject(error);
    });
  }

Gets a publicly-accessible URL for the path from Dropbox and stores it
in ``_itemRefs``.

@return {Promise} a promise for the URL

@private

Gets a publicly - accessible URL for the path from Dropbox and stores it in _itemRefs .


function () {
    var url = 'https://api.dropboxapi.com/2/users/get_current_account';

    return this._request('POST', url, {}).then(function (response) {
      var info = response.responseText;

      try {
        info = JSON.parse(info);
      } catch (e) {
        return Promise.reject(new Error('Could not query current account info: Invalid API response: ' + info));
      }

      return Promise.resolve({
        email: info.email
      });
    });
  }

Fetches the user's info from dropbox and returns a promise for it.

@return {Promise} a promise for user info object (email - the user's email address)

@protected

Fetches the user s info from dropbox and returns a promise for it .


function (path) {
    const url = 'https://api.dropboxapi.com/2/files/delete';
    const requestBody = { path: getDropboxPath(path) };

    return this._request('POST', url, { body: requestBody }).then((response) => {
      if (response.status !== 200 && response.status !== 409) {
        return Promise.resolve({statusCode: response.status});
      }

      var responseBody = response.responseText;

      try {
        responseBody = JSON.parse(responseBody);
      } catch (e) {
        return Promise.reject(new Error('Invalid response body: ' + responseBody));
      }

      if (response.status === 409) {
        if (compareApiError(responseBody, ['path_lookup', 'not_found'])) {
          return Promise.resolve({statusCode: 404});
        }
        return Promise.reject(new Error('API error: ' + responseBody.error_summary));
      }

      return Promise.resolve({statusCode: 200});
    }).then((result) => {
      if (result.statusCode === 200 || result.statusCode === 404) {
        this._revCache.delete(path);
        delete this._itemRefs[path];
      }
      return Promise.resolve(result);
    }, (error) => {
      error.message = 'Could not delete Dropbox file or folder ("' + path + '"): ' + error.message;
      return Promise.reject(error);
    });
  }

Deletes a file or a folder.

@param {string} path - the path to delete

@returns {Promise} A promise for an object with the following structure:
statusCode - HTTP status code

@private


function (path) {
    var url = 'https://api.dropbox.com/2/sharing/list_shared_links';
    var options = {
      body: {
        path: getDropboxPath(path),
        direct_only: true
      }
    };

    return this._request('POST', url, options).then((response) => {
      if (response.status !== 200 && response.status !== 409) {
        return Promise.reject(new Error('Invalid response status: ' + response.status));
      }

      var body;

      try {
        body = JSON.parse(response.responseText);
      } catch (e) {
        return Promise.reject(new Error('Invalid response body: ' + response.responseText));
      }

      if (response.status === 409) {
        return Promise.reject(new Error('API error: ' + response.error_summary));
      }

      if (!body.links.length) {
        return Promise.reject(new Error('No links returned'));
      }

      return Promise.resolve(body.links[0].url);
    }, (error) => {
      error.message = 'Could not get link to a shared file or folder ("' + path + '"): ' + error.message;
      return Promise.reject(error);
    });
  }

Requests the link for an already-shared file or folder.

@param {string} path - path to the file or folder

@returns {Promise} A promise for the shared link

@private

Requests the link for an already - shared file or folder .


function hookSync(rs) {
  if (rs._dropboxOrigSync) { return; } // already hooked
  rs._dropboxOrigSync = rs.sync.sync.bind(rs.sync);
  rs.sync.sync = function () {
    return this.dropbox.fetchDelta.apply(this.dropbox, arguments).
      then(rs._dropboxOrigSync, function (err) {
        rs._emit('error', new Sync.SyncError(err));
        rs._emit('sync-done');
      });
  }.bind(rs);
}

function
hookSync
(
rs
)
{
if
(
rs
.
_dropboxOrigSync
)
{
return
;
}
// already hooked
rs
.
_dropboxOrigSync
=
rs
.
sync
.
sync
.
bind
(
rs
.
sync
)
;
rs
.
sync
.
sync
=
function
(
)
{
return
this
.
dropbox
.
fetchDelta
.
apply
(
this
.
dropbox
,
arguments
)
.
then
(
rs
.
_dropboxOrigSync
,
function
(
err
)
{
rs
.
_emit
(
'error'
,
new
Sync
.
SyncError
(
err
)
)
;
rs
.
_emit
(
'sync-done'
)
;
}
)
;
}
.
bind
(
rs
)
;
}


function unHookSync(rs) {
  if (! rs._dropboxOrigSync) { return; } // not hooked
  rs.sync.sync = rs._dropboxOrigSync;
  delete rs._dropboxOrigSync;
}

function
unHookSync
(
rs
)
{
if
(
!
rs
.
_dropboxOrigSync
)
{
return
;
}
// not hooked
rs
.
sync
.
sync
=
rs
.
_dropboxOrigSync
;
delete
rs
.
_dropboxOrigSync
;
}


function hookSyncCycle(rs) {
  if (rs._dropboxOrigSyncCycle) { return; } // already hooked
  rs._dropboxOrigSyncCycle = rs.syncCycle;
  rs.syncCycle = () => {
    if (rs.sync) {
      hookSync(rs);
      rs._dropboxOrigSyncCycle(arguments);
      unHookSyncCycle(rs);
    } else {
      throw new Error('expected sync to be initialized by now');
    }
  };
}

Hook RemoteStorage.syncCycle as it's the first function called
after RemoteStorage.sync is initialized, so we can then hook
the sync function
@param {object} rs RemoteStorage instance

Hook RemoteStorage . syncCycle as it s the first function called after RemoteStorage . sync is initialized so we can then hook the sync function


function unHookSyncCycle(rs) {
  if (!rs._dropboxOrigSyncCycle) { return; } // not hooked
  rs.syncCycle = rs._dropboxOrigSyncCycle;
  delete rs._dropboxOrigSyncCycle;
}

function
unHookSyncCycle
(
rs
)
{
if
(
!
rs
.
_dropboxOrigSyncCycle
)
{
return
;
}
// not hooked
rs
.
syncCycle
=
rs
.
_dropboxOrigSyncCycle
;
delete
rs
.
_dropboxOrigSyncCycle
;
}

Restore RemoteStorage's syncCycle original implementation
@param {object} rs RemoteStorage instance

Restore RemoteStorage s syncCycle original implementation


function hookGetItemURL (rs) {
  if (rs._origBaseClientGetItemURL) { return; }
  rs._origBaseClientGetItemURL = BaseClient.prototype.getItemURL;
  BaseClient.prototype.getItemURL = function (/*path*/) {
    throw new Error('getItemURL is not implemented for Dropbox yet');
  };
}

Overwrite BaseClient's getItemURL with our own implementation

TODO: getItemURL still needs to be implemented

@param {object} rs - RemoteStorage instance

@private

Overwrite BaseClient s getItemURL with our own implementation


function extractFeatures(chunk) {
    //make it a F32A for efficiency
    var frame = arrayToTyped(chunk);
    //run the extraction of selected features
    var fset = Meyda.extract(featuresToExtract, frame);
    for (let j = 0; j < featuresToExtract.length; j++) {
        var feature = fset[featuresToExtract[j]];
        features[featuresToExtract[j]].push(feature);
    }
  }

helper method to extract features for this chunk


function getIdFromURL (url) {
  var id = url.replace(youtubeRegexp, '$1');

  if (id.includes(';')) {
    var pieces = id.split(';');

    if (pieces[1].includes('%')) {
      var uriComponent = decodeURIComponent(pieces[1]);
      id = ("http://youtube.com" + uriComponent).replace(youtubeRegexp, '$1');
    } else {
      id = pieces[0];
    }
  } else if (id.includes('#')) {
    id = id.split('#')[0];
  }

  return id
}

function getIdFromURL ( url ) { var id = url . replace ( youtubeRegexp , '$1' ) ; if ( id . includes ( ';' ) ) { var pieces = id . split ( ';' ) ; if ( pieces [ 1 ] . includes ( '%' ) ) { var uriComponent = decodeURIComponent ( pieces [ 1 ] ) ; id = ( "http://youtube.com" + uriComponent ) . replace ( youtubeRegexp , '$1' ) ; } else { id = pieces [ 0 ] ; } } else if ( id . includes ( '#' ) ) { id = id . split ( '#' ) [ 0 ] ; } return id }

get id from url
@param  {string} url url
@return {string}     id


function getTimeFromURL (url) {
  if ( url === void 0 ) url = '';

  var times = url.match(timeRegexp);

  if (!times) {
    return 0
  }

  var full = times[0];
  var minutes = times[1];
  var seconds = times[2];

  if (typeof seconds !== 'undefined') {
    seconds = parseInt(seconds, 10);
    minutes = parseInt(minutes, 10);
  } else if (full.includes('m')) {
    minutes = parseInt(minutes, 10);
    seconds = 0;
  } else {
    seconds = parseInt(minutes, 10);
    minutes = 0;
  }

  return seconds + (minutes * 60)
}

function getTimeFromURL ( url ) { if ( url === void 0 ) url = '' ; var times = url . match ( timeRegexp ) ; if ( ! times ) { return 0 } var full = times [ 0 ] ; var minutes = times [ 1 ] ; var seconds = times [ 2 ] ; if ( typeof seconds !== 'undefined' ) { seconds = parseInt ( seconds , 10 ) ; minutes = parseInt ( minutes , 10 ) ; } else if ( full . includes ( 'm' ) ) { minutes = parseInt ( minutes , 10 ) ; seconds = 0 ; } else { seconds = parseInt ( minutes , 10 ) ; minutes = 0 ; } return seconds + ( minutes * 60 ) }

get time from url
@param  {string} url url
@return {number}     time


function onTablesSelected(tables) {
    // Assign partialed functions to make the code slightly more readable
    steps.collect = mapValues(steps.collect, function(method) {
        return partial(method, adapter, { tables: tables });
    });

    // Collect the data in parallel
    async.parallel(steps.collect, onTableDataCollected);
}

When tables have been selected, fetch data for those tables

When tables have been selected fetch data for those tables


function onTableDataCollected(err, data) {
    bailOnError(err);

    var tableName, models = {}, model;
    for (tableName in data.tableStructure) {
        model = steps.tableToObject({
            name: tableName,
            columns: data.tableStructure[tableName],
            comment: data.tableComments[tableName]
        }, opts);

        models[model.name] = model;
    }

    data.models = steps.findReferences(models);

    // Note: This mutates the models - sorry. PRs are welcome.
    steps.findOneToManyReferences(adapter, data.models, function(refErr) {
        if (refErr) {
            throw refErr;
        }

        data.types = steps.generateTypes(data, opts);

        adapter.close();
        steps.outputData(data, opts, onDataOutput);
    });
}

When table data has been collected, build an object representation of them

When table data has been collected build an object representation of them


function getOffset(cursor, defaultOffset) {
    if (typeof cursor === 'undefined' || cursor === null) {
        return defaultOffset;
    }

    let offset = cursorToOffset(cursor);
    if (isNaN(offset)) {
        return defaultOffset;
    }

    return offset;
}

function getOffset ( cursor , defaultOffset ) { if ( typeof cursor === 'undefined' || cursor === null ) { return defaultOffset ; } let offset = cursorToOffset ( cursor ) ; if ( isNaN ( offset ) ) { return defaultOffset ; } return offset ; }

Given an optional cursor and a default offset, returns the offset to use; if the cursor contains a valid offset, that will be used, otherwise it will be the default.

Given an optional cursor and a default offset returns the offset to use ; if the cursor contains a valid offset that will be used otherwise it will be the default .


function importSpecifier(name, def) {
    return {
        type: def === true ? 'ImportDefaultSpecifier' : 'ImportSpecifier',
        id: {
            type: 'Identifier',
            name: name
        },
        name: null
    };
}

function importSpecifier ( name , def ) { return { type : def === true ? 'ImportDefaultSpecifier' : 'ImportSpecifier' , id : { type : 'Identifier' , name : name } , name : null } ; }


function ruleCodes(flags, value) {
  var flag = flags.FLAG
  var result = []
  var length
  var index

  if (!value) {
    return result
  }

  if (flag === 'long') {
    index = 0
    length = value.length

    while (index < length) {
      result.push(value.substr(index, 2))

      index += 2
    }

    return result
  }

  return value.split(flag === 'num' ? ',' : '')
}

function ruleCodes ( flags , value ) { var flag = flags . FLAG var result = [ ] var length var index if ( ! value ) { return result } if ( flag === 'long' ) { index = 0 length = value . length while ( index < length ) { result . push ( value . substr ( index , 2 ) ) index += 2 } return result } return value . split ( flag === 'num' ? ',' : '' ) }


function add(buf) {
  var self = this
  var flags = self.flags
  var lines = buf.toString('utf8').split('\n')
  var length = lines.length
  var index = -1
  var line
  var forbidden
  var word
  var model
  var flag

  // Ensure there’s a key for `FORBIDDENWORD`: `false` cannot be set through an
  // affix file so its safe to use as a magic constant.
  flag = flags.FORBIDDENWORD || false
  flags.FORBIDDENWORD = flag

  while (++index < length) {
    line = trim(lines[index])

    if (!line) {
      continue
    }

    line = line.split('/')
    word = line[0]
    model = line[1]
    forbidden = word.charAt(0) === '*'

    if (forbidden) {
      word = word.slice(1)
    }

    self.add(word, model)

    if (forbidden) {
      self.data[word].push(flag)
    }
  }

  return self
}


function generate(context, memory, words, edits) {
  var characters = context.flags.TRY
  var characterLength = characters.length
  var data = context.data
  var flags = context.flags
  var result = []
  var upper
  var length
  var index
  var word
  var position
  var count
  var before
  var after
  var nextAfter
  var nextNextAfter
  var character
  var nextCharacter
  var inject
  var offset

  // Check the pre-generated edits.
  length = edits && edits.length
  index = -1

  while (++index < length) {
    check(edits[index], true)
  }

  // Iterate over given word.
  length = words.length
  index = -1

  while (++index < length) {
    word = words[index]

    before = ''
    character = ''
    nextAfter = word
    nextNextAfter = word.slice(1)
    nextCharacter = word.charAt(0)
    position = -1
    count = word.length + 1

    // Iterate over every character (including the end).
    while (++position < count) {
      before += character
      after = nextAfter
      nextAfter = nextNextAfter
      nextNextAfter = nextAfter.slice(1)
      character = nextCharacter
      nextCharacter = word.charAt(position + 1)
      upper = character.toLowerCase() !== character

      // Remove.
      check(before + nextAfter)

      // Switch.
      if (nextAfter) {
        check(before + nextCharacter + character + nextNextAfter)
      }

      // Iterate over all possible letters.
      offset = -1

      while (++offset < characterLength) {
        inject = characters[offset]

        // Add and replace.
        check(before + inject + after)
        check(before + inject + nextAfter)

        // Try upper-case if the original character was upper-cased.
        if (upper) {
          inject = inject.toUpperCase()

          check(before + inject + after)
          check(before + inject + nextAfter)
        }
      }
    }
  }

  // Return the list of generated words.
  return result

  // Check and handle a generated value.
  function check(value, double) {
    var state = memory.state[value]
    var corrected

    if (state !== Boolean(state)) {
      result.push(value)

      corrected = form(context, value)
      state = corrected && !flag(flags, noSuggestType, data[corrected])

      memory.state[value] = state

      if (state) {
        memory.weighted[value] = double ? 10 : 0
        memory.suggestions.push(value)
      }
    }

    if (state) {
      memory.weighted[value]++
    }
  }
}

Get a list of values close in edit distance to `words`.

Get a list of values close in edit distance to words .


function check(value, double) {
    var state = memory.state[value]
    var corrected

    if (state !== Boolean(state)) {
      result.push(value)

      corrected = form(context, value)
      state = corrected && !flag(flags, noSuggestType, data[corrected])

      memory.state[value] = state

      if (state) {
        memory.weighted[value] = double ? 10 : 0
        memory.suggestions.push(value)
      }
    }

    if (state) {
      memory.weighted[value]++
    }
  }

function check ( value , double ) { var state = memory . state [ value ] var corrected if ( state !== Boolean ( state ) ) { result . push ( value ) corrected = form ( context , value ) state = corrected && ! flag ( flags , noSuggestType , data [ corrected ] ) memory . state [ value ] = state if ( state ) { memory . weighted [ value ] = double ? 10 : 0 memory . suggestions . push ( value ) } } if ( state ) { memory . weighted [ value ] ++ } }


function add(word, rules) {
    // Some dictionaries will list the same word multiple times with different
    // rule sets.
    var curr = (own.call(dict, word) && dict[word]) || []
    dict[word] = curr.concat(rules || [])
  }


function flag(values, value, flags) {
  return flags && own.call(values, value) && flags.indexOf(values[value]) !== -1
}

function flag ( values , value , flags ) { return flags && own . call ( values , value ) && flags . indexOf ( values [ value ] ) !== - 1 }


function normalize(value, patterns) {
  var length = patterns.length
  var index = -1
  var pattern

  while (++index < length) {
    pattern = patterns[index]
    value = value.replace(pattern[0], pattern[1])
  }

  return value
}

function normalize ( value , patterns ) { var length = patterns . length var index = - 1 var pattern while ( ++ index < length ) { pattern = patterns [ index ] value = value . replace ( pattern [ 0 ] , pattern [ 1 ] ) } return value }


function form(context, value, all) {
  var dict = context.data
  var flags = context.flags
  var alternative

  value = trim(value)

  if (!value) {
    return null
  }

  value = normalize(value, context.conversion.in)

  if (exact(context, value)) {
    if (!all && flag(flags, 'FORBIDDENWORD', dict[value])) {
      return null
    }

    return value
  }

  // Try sentence-case if the value is upper-case.
  if (value.toUpperCase() === value) {
    alternative = value.charAt(0) + value.slice(1).toLowerCase()

    if (ignore(flags, dict[alternative], all)) {
      return null
    }

    if (exact(context, alternative)) {
      return alternative
    }
  }

  // Try lower-case.
  alternative = value.toLowerCase()

  if (alternative !== value) {
    if (ignore(flags, dict[alternative], all)) {
      return null
    }

    if (exact(context, alternative)) {
      return alternative
    }
  }

  return null
}


function NSpell(aff, dic) {
  var length
  var index
  var dictionaries

  if (!(this instanceof NSpell)) {
    return new NSpell(aff, dic)
  }

  if (typeof aff === 'string' || buffer(aff)) {
    if (typeof dic === 'string' || buffer(dic)) {
      dictionaries = [{dic: dic}]
    }
  } else if (aff) {
    if ('length' in aff) {
      dictionaries = aff
      aff = aff[0] && aff[0].aff
    } else {
      if (aff.dic) {
        dictionaries = [aff]
      }

      aff = aff.aff
    }
  }

  if (!aff) {
    throw new Error('Missing `aff` in dictionary')
  }

  aff = affix(aff)

  this.data = {}
  this.compoundRuleCodes = aff.compoundRuleCodes
  this.replacementTable = aff.replacementTable
  this.conversion = aff.conversion
  this.compoundRules = aff.compoundRules
  this.rules = aff.rules
  this.flags = aff.flags

  length = dictionaries ? dictionaries.length : 0
  index = -1

  while (++index < length) {
    dic = dictionaries[index]

    if (dic && dic.dic) {
      this.dictionary(dic.dic)
    }
  }
}

function
NSpell
(
aff
,
dic
)
{
var
length
var
index
var
dictionaries
if
(
!
(
this
instanceof
NSpell
)
)
{
return
new
NSpell
(
aff
,
dic
)
}
if
(
typeof
aff
===
'string'
||
buffer
(
aff
)
)
{
if
(
typeof
dic
===
'string'
||
buffer
(
dic
)
)
{
dictionaries
=
[
{
dic
:
dic
}
]
}
}
else
if
(
aff
)
{
if
(
'length'
in
aff
)
{
dictionaries
=
aff
aff
=
aff
[
0
]
&&
aff
[
0
]
.
aff
}
else
{
if
(
aff
.
dic
)
{
dictionaries
=
[
aff
]
}
aff
=
aff
.
aff
}
}
if
(
!
aff
)
{
throw
new
Error
(
'Missing `aff` in dictionary'
)
}
aff
=
affix
(
aff
)
this
.
data
=
{
}
this
.
compoundRuleCodes
=
aff
.
compoundRuleCodes
this
.
replacementTable
=
aff
.
replacementTable
this
.
conversion
=
aff
.
conversion
this
.
compoundRules
=
aff
.
compoundRules
this
.
rules
=
aff
.
rules
this
.
flags
=
aff
.
flags
length
=
dictionaries
dictionaries
.
length
:
0
index
=
1
while
(
++
index
<
length
)
{
dic
=
dictionaries
[
index
]
if
(
dic
&&
dic
.
dic
)
{
this
.
dictionary
(
dic
.
dic
)
}
}
}


function add(value, model) {
  var self = this
  var dict = self.data
  var codes = model && own.call(dict, model) ? dict[model].concat() : []

  push(dict, value, codes, self)

  return self
}

function add ( value , model ) { var self = this var dict = self . data var codes = model && own . call ( dict , model ) ? dict [ model ] . concat ( ) : [ ] push ( dict , value , codes , self ) return self }


function parse(buf, options, dict) {
  var index
  var last
  var value

  // Parse as lines.
  value = buf.toString(UTF8)
  last = value.indexOf(linefeed) + 1
  index = value.indexOf(linefeed, last)

  while (index !== -1) {
    if (value.charCodeAt(last) !== tab) {
      parseLine(value.slice(last, index), options, dict)
    }

    last = index + 1
    index = value.indexOf(linefeed, last)
  }

  parseLine(value.slice(last), options, dict)
}

function
parse
(
buf
,
options
,
dict
)
{
var
index
var
last
var
value
// Parse as lines.
value
=
buf
.
toString
(
UTF8
)
last
=
value
.
indexOf
(
linefeed
)
+
1
index
=
value
.
indexOf
(
linefeed
,
last
)
while
(
index
!==
1
)
{
if
(
value
.
charCodeAt
(
last
)
!==
tab
)
{
parseLine
(
value
.
slice
(
last
,
index
)
,
options
,
dict
)
}
last
=
index
+
1
index
=
value
.
indexOf
(
linefeed
,
last
)
}
parseLine
(
value
.
slice
(
last
)
,
options
,
dict
)
}


function parseLine(line, options, dict) {
  var word
  var codes
  var result
  var hashOffset
  var slashOffset

  // Find offsets.
  slashOffset = line.indexOf(slash)
  while (slashOffset !== -1 && line.charAt(slashOffset - 1) === backslash) {
    line = line.slice(0, slashOffset - 1) + line.slice(slashOffset)
    slashOffset = line.indexOf(slash, slashOffset)
  }

  hashOffset = line.indexOf(numberSign)

  // Handle hash and slash offsets.  Note that hash can be a valid flag, so we
  // should not just discard all string after it.
  if (hashOffset >= 0) {
    if (slashOffset >= 0 && slashOffset < hashOffset) {
      word = line.slice(0, slashOffset)
      whiteSpaceExpression.lastIndex = slashOffset + 1
      result = whiteSpaceExpression.exec(line)
      codes = line.slice(slashOffset + 1, result ? result.index : undefined)
    } else {
      word = line.slice(0, hashOffset)
    }
  } else if (slashOffset >= 0) {
    word = line.slice(0, slashOffset)
    codes = line.slice(slashOffset + 1)
  } else {
    word = line
  }

  word = trim(word)
  if (word) {
    codes = parseCodes(options.flags, codes && trim(codes))
    add(dict, word, codes, options)
  }
}


function casing(value) {
  var head = exact(value.charAt(0))
  var rest = value.slice(1)

  if (!rest) {
    return head
  }

  rest = exact(rest)

  if (head === rest) {
    return head
  }

  if (head === 'u' && rest === 'l') {
    return 's'
  }

  return null
}

function casing ( value ) { var head = exact ( value . charAt ( 0 ) ) var rest = value . slice ( 1 ) if ( ! rest ) { return head } rest = exact ( rest ) if ( head === rest ) { return head } if ( head === 'u' && rest === 'l' ) { return 's' } return null }


function apply(value, rule, rules) {
  var entries = rule.entries
  var words = []
  var index = -1
  var length = entries.length
  var entry
  var next
  var continuationRule
  var continuation
  var position
  var count

  while (++index < length) {
    entry = entries[index]

    if (!entry.match || value.match(entry.match)) {
      next = value

      if (entry.remove) {
        next = next.replace(entry.remove, '')
      }

      if (rule.type === 'SFX') {
        next += entry.add
      } else {
        next = entry.add + next
      }

      words.push(next)

      continuation = entry.continuation

      if (continuation && continuation.length !== 0) {
        position = -1
        count = continuation.length

        while (++position < count) {
          continuationRule = rules[continuation[position]]

          if (continuationRule) {
            words = words.concat(apply(next, continuationRule, rules))
          }
        }
      }
    }
  }

  return words
}

function apply ( value , rule , rules ) { var entries = rule . entries var words = [ ] var index = - 1 var length = entries . length var entry var next var continuationRule var continuation var position var count while ( ++ index < length ) { entry = entries [ index ] if ( ! entry . match || value . match ( entry . match ) ) { next = value if ( entry . remove ) { next = next . replace ( entry . remove , '' ) } if ( rule . type === 'SFX' ) { next += entry . add } else { next = entry . add + next } words . push ( next ) continuation = entry . continuation if ( continuation && continuation . length !== 0 ) { position = - 1 count = continuation . length while ( ++ position < count ) { continuationRule = rules [ continuation [ position ] ] if ( continuationRule ) { words = words . concat ( apply ( next , continuationRule , rules ) ) } } } } } return words }


function spell(word) {
  var self = this
  var dict = self.data
  var flags = self.flags
  var value = form(self, word, true)

  // Hunspell also provides `root` (root word of the input word), and `compound`
  // (whether `word` was compound).
  return {
    correct: self.correct(word),
    forbidden: Boolean(value && flag(flags, 'FORBIDDENWORD', dict[value])),
    warn: Boolean(value && flag(flags, 'WARN', dict[value]))
  }
}


function add(buf) {
  var self = this
  var compound = self.compoundRules
  var compoundCodes = self.compoundRuleCodes
  var index = -1
  var length = compound.length
  var rule
  var source
  var character
  var offset
  var count

  parse(buf, self, self.data)

  // Regenerate compound expressions.
  while (++index < length) {
    rule = compound[index]
    source = ''

    offset = -1
    count = rule.length

    while (++offset < count) {
      character = rule.charAt(offset)

      if (compoundCodes[character].length === 0) {
        source += character
      } else {
        source += '(?:' + compoundCodes[character].join('|') + ')'
      }
    }

    compound[index] = new RegExp(source, 'i')
  }

  return self
}

function
add
(
buf
)
{
var
self
=
this
var
compound
=
self
.
compoundRules
var
compoundCodes
=
self
.
compoundRuleCodes
var
index
=
1
var
length
=
compound
.
length
var
rule
var
source
var
character
var
offset
var
count
parse
(
buf
,
self
,
self
.
data
)
// Regenerate compound expressions.
while
(
++
index
<
length
)
{
rule
=
compound
[
index
]
source
=
''
offset
=
1
count
=
rule
.
length
while
(
++
offset
<
count
)
{
character
=
rule
.
charAt
(
offset
)
if
(
compoundCodes
[
character
]
.
length
===
0
)
{
source
+=
character
}
else
{
source
+=
'(?:'
+
compoundCodes
[
character
]
.
join
(
'|'
)
+
')'
}
}
compound
[
index
]
=
new
RegExp
(
source
,
'i'
)
}
return
self
}


function exact(context, value) {
  var data = context.data
  var flags = context.flags
  var codes = own.call(data, value) ? data[value] : null
  var compound
  var index
  var length

  if (codes) {
    return !flag(flags, 'ONLYINCOMPOUND', codes)
  }

  compound = context.compoundRules
  length = compound.length
  index = -1

  // Check if this might be a compound word.
  if (value.length >= flags.COMPOUNDMIN) {
    while (++index < length) {
      if (value.match(compound[index])) {
        return true
      }
    }
  }

  return false
}


function() {
    var retVal, parsedOptions;

    if (this.model) {
      retVal = this.model.toJSON();
    } else if (this.collection) {
      retVal = {
        models: this.collection.toJSON(),
        meta: this.collection.meta,
        params: this.collection.params
      };
    }

    // Remove options that are duplicates in the templates
    parsedOptions = _.omit(this.options, ['model', 'collection', 'app']);
    return _.extend({}, retVal, parsedOptions);
  }

Get data for template.  This also acts as a view-model.
Try to return proper data if model or collection is available.

Get data for template . This also acts as a view - model . Try to return proper data if model or collection is available .


function(data) {
    if (this.app) {
      data._app = this.app;
    }
    if (this.model) {
      data._model = this.model;
    }
    if (this.collection) {
      data._collection = this.collection;
    }
    data._view = this;
    return data;
  }

function ( data ) { if ( this . app ) { data . _app = this . app ; } if ( this . model ) { data . _model = this . model ; } if ( this . collection ) { data . _collection = this . collection ; } data . _view = this ; return data ; }

Add special properties `_app` and `_model` or `_collection` to pass to
the templates.

Add special properties _app and _model or _collection to pass to the templates .


function() {
    var attributes = {},
        fetchSummary = {},
        modelUtils = this.app.modelUtils,
        nonAttributeOptions = this.nonAttributeOptions;

    if (this.attributes) {
      _.extend(attributes, _.result(this, 'attributes'));
    }
    if (this.id) {
      attributes.id = _.result(this, "id");
    }
    if (this.className) {
      attributes['class'] = _.result(this, "className");
    }

    // Add `data-view` attribute with view key.
    // For now, view key is same as template.
    attributes['data-view'] = this.name;

    // Add model & collection meta data from options,
    // as well as any non-object option values.
    _.each(this.options, function(value, key) {

        if (!_.isObject(value) && !_.include(nonAttributeOptions, key)) {
          attributes["data-" + key] = value;
        }
    });
    fetchSummary = BaseView.extractFetchSummary(modelUtils, this.options);

    if (!_.isEmpty(fetchSummary)) {
      attributes['data-fetch_summary'] = JSON.stringify(fetchSummary);
    }
    return attributes;
  }


function() {
    var template = this.getTemplate(),
        data;

    this._preRender();
    data = this.getTemplateData();
    data = this.decorateTemplateData(data);
    if (template == null) {
      throw new Error(this.name + ": template \"" + this.getTemplateName() + "\" not found.");
    }
    return template(data);
  }

function
(
)
{
var
template
=
this
.
getTemplate
(
)
,
data
;
this
.
_preRender
(
)
;
data
=
this
.
getTemplateData
(
)
;
data
=
this
.
decorateTemplateData
(
data
)
;
if
(
template
==
)
{
throw
new
Error
(
this
.
name
+
": template \""
+
this
.
getTemplateName
(
)
+
"\" not found."
)
;
}
return
template
(
data
)
;
}

Turn template into HTML, minus the wrapper element.

Turn template into HTML minus the wrapper element .


function() {
    var html = this.getInnerHtml(),
        attributes = this.getAttributes(),
        tagName = _.result(this, "tagName"),
        attrString;

    attrString = _.inject(attributes, function(memo, value, key) {
      return memo += " " + key + "=\"" + _.escape(value) + "\"";
    }, '');

    return "<" + tagName + attrString + ">" + html + "</" + tagName + ">";
  }

function
(
)
{
var
html
=
this
.
getInnerHtml
(
)
,
attributes
=
this
.
getAttributes
(
)
,
tagName
=
_
.
result
(
this
,
"tagName"
)
,
attrString
;
attrString
=
_
.
inject
(
attributes
,
function
(
memo
,
value
,
key
)
{
return
memo
+=
" "
+
key
+
"=\""
+
_
.
escape
(
value
)
+
"\""
;
}
,
''
)
;
return
"<"
+
tagName
+
attrString
+
">"
+
html
+
"</"
+
tagName
+
">"
;
}

Get the HTML for the view, including the wrapper element.

Get the HTML for the view including the wrapper element .


function() {
    var params = {},
        fetchOptions,
        fetchSpec;

    if (this.options.fetch_params) {
      if (!_.isObject(this.options.fetch_params)) {
        throw new Error('fetch_params must be an object for lazy loaded views');
      }

      params = this.options.fetch_params;
    } else if (this.options.param_name) {
      params[this.options.param_name] = this.options.param_value;
    }

    if (this.options.fetch_options) {
      if (!_.isObject(this.options.fetch_options)) {
        throw new Error('fetch_options must be an object for lazy loaded views');
      }

      fetchOptions = this.options.fetch_options;
    }

    if (this.options.model_id != null) {
      params.id = this.options.model_id;
    }

    if (this.options.model_name != null) {
      fetchSpec = {
        model: {
          model: this.options.model_name,
          params: params
        }
      };
    } else if (this.options.collection_name != null) {
      fetchSpec = {
        collection: {
          collection: this.options.collection_name,
          params: params
        }
      };
    }

    // Allow ability to just pass the full "spec" to a lazy loaded view
    if (this.options.fetch_spec) {
      if (!_.isObject(this.options.fetch_spec)) {
        throw new Error('fetch_spec must be an object for lazy loaded views');
      }

      fetchSpec = this.options.fetch_spec;
    }

    this.setLoading(true);

    this._preRender();
    this.app.fetch(fetchSpec, fetchOptions, this._fetchLazyCallback.bind(this));
  }

If rendered on the client missing its data,
fetch it based on the parameters passed in.

If rendered on the client missing its data fetch it based on the parameters passed in .


function getAppAttributes(attrs, req, res) {
      if (typeof attrs === 'function') {
        attrs = attrs(req, res);
      }
      return attrs || {};
    }

function getAppAttributes ( attrs , req , res ) { if ( typeof attrs === 'function' ) { attrs = attrs ( req , res ) ; } return attrs || { } ; }

Allow `appAttributes` to be a function for lazy-instantiation based on `req` and `res`.

Allow appAttributes to be a function for lazy - instantiation based on req and res .


function actionCall(action, params) {
    action.call(router, params, router.getRenderCallback(route));
  }

function actionCall ( action , params ) { action . call ( router , params , router . getRenderCallback ( route ) ) ; }


function(pattern, controller, options) {
    var realAction, action, handler, route, routeObj, routerContext = this;

    route = parseRouteDefinitions([controller, options]);
    realAction = this.getAction(route);

    if (isServer) {
      action = realAction;
    } else {
      action = function(params, callback) {
        var self = this;
        var myLoadNumber = ++loadNumber;
        function next() {
          // To prevent race conditions we ensure that no future requests have been processed in the mean time.
          if (myLoadNumber === loadNumber) {
            callback.apply(self, arguments);
          }
        }
        // in AMD environment realAction is the string containing path to the controller
        // which will be loaded async (might be preloaded)
        // Only used in AMD environment
        if (typeof realAction === 'string') {
          routerContext._requireAMD([realAction], function(controller) {
            // check we have everything we need
            if (typeof controller[route.action] != 'function') {
              throw new Error("Missing action \"" + route.action + "\" for controller \"" + route.controller + "\"");
            }
            controller[route.action].call(self, params, next);
          });
        }
        else {
          realAction.call(self, params, next);
        }
      }
    }

    if (!(pattern instanceof RegExp) && pattern.slice(0, 1) !== '/') {
      pattern = "/" + pattern;
    }

    handler = this.getHandler(action, pattern, route);
    routeObj = [pattern, route, handler];

    this._routes.push(routeObj);
    this.trigger('route:add', routeObj);

    return routeObj;
  }

Method passed to routes file to build up routes definition.
Adds a single route definition.

Method passed to routes file to build up routes definition . Adds a single route definition .


function unmarshalPublicKey (curve, key) {
  const byteLen = curveLengths[curve]

  if (!key.slice(0, 1).equals(Buffer.from([4]))) {
    throw new Error('Invalid key format')
  }
  const x = new BN(key.slice(1, byteLen + 1))
  const y = new BN(key.slice(1 + byteLen))

  return {
    kty: 'EC',
    crv: curve,
    x: toBase64(x, byteLen),
    y: toBase64(y, byteLen),
    ext: true
  }
}

function
unmarshalPublicKey
(
curve
,
key
)
{
const
byteLen
=
curveLengths
[
curve
]
if
(
!
key
.
slice
(
0
,
1
)
.
equals
(
Buffer
.
from
(
[
4
]
)
)
)
{
throw
new
Error
(
'Invalid key format'
)
}
const
x
=
new
BN
(
key
.
slice
(
1
,
byteLen
+
1
)
)
const
y
=
new
BN
(
key
.
slice
(
1
+
byteLen
)
)
return
{
kty
:
'EC'
,
crv
:
curve
,
x
:
toBase64
(
x
,
byteLen
)
,
y
:
toBase64
(
y
,
byteLen
)
,
ext
:
true
}
}

Unmarshal converts a point, serialized by Marshal, into an jwk encoded key

Unmarshal converts a point serialized by Marshal into an jwk encoded key


function pbkdf2 (password, salt, iterations, keySize, hash) {
  const hasher = hashName[hash]
  if (!hasher) {
    throw new Error(`Hash '${hash}' is unknown or not supported`)
  }
  const dek = forgePbkdf2(
    password,
    salt,
    iterations,
    keySize,
    hasher)
  return forgeUtil.encode64(dek)
}

function pbkdf2 ( password , salt , iterations , keySize , hash ) { const hasher = hashName [ hash ] if ( ! hasher ) { throw new Error ( ` ${ hash } ` ) } const dek = forgePbkdf2 ( password , salt , iterations , keySize , hasher ) return forgeUtil . encode64 ( dek ) }

Computes the Password-Based Key Derivation Function 2.

@param {string} password
@param {string} salt
@param {number} iterations
@param {number} keySize (in bytes)
@param {string} hash - The hash name ('sha1', 'sha2-512, ...)
@returns {string} - A new password

Computes the Password - Based Key Derivation Function 2 .


function getRawHeader(_block) {
  if (typeof _block.difficulty !== 'string') {
    _block.difficulty = '0x' + _block.difficulty.toString(16)
  }

  const block = new EthereumBlock(_block)
  return block.header
}

function getRawHeader ( _block ) { if ( typeof _block . difficulty !== 'string' ) { _block . difficulty = '0x' + _block . difficulty . toString ( 16 ) } const block = new EthereumBlock ( _block ) return block . header }


function initMatic() {
  if (!matic) {
    matic = new Matic({
      maticProvider: process.env.MATIC_PROVIDER,
      parentProvider: process.env.PARENT_PROVIDER,
      rootChainAddress: process.env.ROOTCHAIN_ADDRESS,
      maticWethAddress: process.env.MATIC_WETH_ADDRESS,
      syncerUrl: process.env.SYNCER_URL,
      watcherUrl: process.env.WATCHER_URL,
      withdrawManagerAddress: process.env.WITHDRAWMANAGER_ADDRESS,
    })

    matic.wallet = '<private-key>' // your private key
  }
}

function
initMatic
(
)
{
if
(
!
matic
)
{
matic
=
new
Matic
(
{
maticProvider
:
process
.
env
.
MATIC_PROVIDER
,
parentProvider
:
process
.
env
.
PARENT_PROVIDER
,
rootChainAddress
:
process
.
env
.
ROOTCHAIN_ADDRESS
,
maticWethAddress
:
process
.
env
.
MATIC_WETH_ADDRESS
,
syncerUrl
:
process
.
env
.
SYNCER_URL
,
watcherUrl
:
process
.
env
.
WATCHER_URL
,
withdrawManagerAddress
:
process
.
env
.
WITHDRAWMANAGER_ADDRESS
,
}
)
matic
.
wallet
=
'<private-key>'
// your private key
}
}


function matchPath(pathname, options = {}) {
  if (typeof options === 'string') options = { path: options };

  const {
    path, exact = false, strict = false, sensitive = false
  } = options;

  const paths = [].concat(path);

  return paths.reduce((matched, p) => {
    if (matched) return matched;
    const { regexp, keys } = compilePath(p, {
      end: exact,
      strict,
      sensitive
    });
    const match = regexp.exec(pathname);

    if (!match) return null;

    const [url, ...values] = match;
    const isExact = pathname === url;

    if (exact && !isExact) return null;

    return {
      path: p, // the p used to match
      url: p === '/' && url === '' ? '/' : url, // the matched portion of the URL
      isExact, // whether or not we matched exactly
      params: keys.reduce((memo, key, index) => {
        memo[key.name] = values[index];
        return memo;
      }, {})
    };
  }, null);
}

function
matchPath
(
pathname
,
options
=
{
}
)
{
if
(
typeof
options
===
'string'
)
options
=
{
path
:
options
}
;
const
{
path
,
exact
=
false
,
strict
=
false
,
sensitive
=
false
}
=
options
;
const
paths
=
[
]
.
concat
(
path
)
;
return
paths
.
reduce
(
(
matched
,
p
)
=>
{
if
(
matched
)
return
matched
;
const
{
regexp
,
keys
}
=
compilePath
(
p
,
{
end
:
exact
,
strict
,
sensitive
}
)
;
const
match
=
regexp
.
exec
(
pathname
)
;
if
(
!
match
)
return
;
const
[
url
,
...
values
]
=
match
;
const
isExact
=
pathname
===
url
;
if
(
exact
&&
!
isExact
)
return
;
return
{
path
:
p
,
// the p used to match
url
:
p
===
'/'
&&
url
===
''
'/'
:
url
,
// the matched portion of the URL
isExact
,
// whether or not we matched exactly
params
:
keys
.
reduce
(
(
memo
,
key
,
index
)
=>
{
memo
[
key
.
name
]
=
values
[
index
]
;
return
memo
;
}
,
{
}
)
}
;
}
,
)
;
}

Public API for matching a URL pathname to a path.

Public API for matching a URL pathname to a path .


function Redirect({ computedMatch, to, push = false }) {
  return (
    <RouterContext.Consumer>
      {(context) => {
        invariant(context, 'You should not use <Redirect> outside a <Router>');

        const { history, staticContext } = context;

        const method = push ? history.push : history.replace;
        const location = createLocation(
          computedMatch
            ? typeof to === 'string'
              ? generatePath(to, computedMatch.params)
              : {
                ...to,
                pathname: generatePath(to.pathname, computedMatch.params)
              }
            : to
        );

        // When rendering in a static context,
        // set the new location immediately.
        if (staticContext) {
          method(location);
          return null;
        }

        return (
          <Lifecycle
            onMount={() => {
              method(location);
            }}
            onUpdate={(self, prevProps) => {
              const prevLocation = createLocation(prevProps.to);
              if (
                !locationsAreEqual(prevLocation, {
                  ...location,
                  key: prevLocation.key
                })
              ) {
                method(location);
              }
            }}
            to={to}
          />
        );
      }}
    </RouterContext.Consumer>
  );
}

The public API for navigating programmatically with a component.

The public API for navigating programmatically with a component .


function entities(state = { users: {}, repos: {} }, action) {
  if (action.response && action.response.entities) {
    return merge({}, state, action.response.entities)
  }

  return state
}

function entities ( state = { users : { } , repos : { } } , action ) { if ( action . response && action . response . entities ) { return merge ( { } , state , action . response . entities ) } return state }

Updates an entity cache in response to any action with response.entities.

Updates an entity cache in response to any action with response . entities .


function errorMessage(state = null, action) {
  const { type, error } = action

  if (type === ActionTypes.RESET_ERROR_MESSAGE) {
    return null
  } else if (error) {
    return action.error
  }

  return state
}

function errorMessage ( state = null , action ) { const { type , error } = action if ( type === ActionTypes . RESET_ERROR_MESSAGE ) { return null } else if ( error ) { return action . error } return state }

Updates error message to notify about the failed fetches.

Updates error message to notify about the failed fetches .


function cancelMain() {
    if (mainTask.isRunning && !mainTask.isCancelled) {
      mainTask.isCancelled = true
      next(TASK_CANCEL)
    }
  }

function cancelMain ( ) { if ( mainTask . isRunning && ! mainTask . isCancelled ) { mainTask . isCancelled = true next ( TASK_CANCEL ) } }

cancellation of the main task. We'll simply resume the Generator with a Cancel

cancellation of the main task . We ll simply resume the Generator with a Cancel


function currCb(res, isErr) {
      if (effectSettled) {
        return
      }

      effectSettled = true
      cb.cancel = noop // defensive measure
      if (sagaMonitor) {
        isErr ? sagaMonitor.effectRejected(effectId, res) : sagaMonitor.effectResolved(effectId, res)
      }
      cb(res, isErr)
    }

function
currCb
(
res
,
isErr
)
{
if
(
effectSettled
)
{
return
}
effectSettled
=
true
cb
.
cancel
=
noop
// defensive measure
if
(
sagaMonitor
)
{
isErr
sagaMonitor
.
effectRejected
(
effectId
,
res
)
:
sagaMonitor
.
effectResolved
(
effectId
,
res
)
}
cb
(
res
,
isErr
)
}

Completion callback passed to the appropriate effect runner


function updateAttributes(el, prevProps, props) {
  var propName;

  if (!props || prevProps === props) {
    return;
  }

  // Set attributes.
  for (propName in props) {
    if (!filterNonEntityPropNames(propName)) {
      continue;
    }
    doSetAttribute(el, props, propName);
  }

  // See if attributes were removed.
  if (prevProps) {
    for (propName in prevProps) {
      if (!filterNonEntityPropNames(propName)) {
        continue;
      }
      if (props[propName] === undefined) {
        el.removeAttribute(propName);
      }
    }
  }
}

function
updateAttributes
(
el
,
prevProps
,
props
)
{
var
propName
;
if
(
!
props
||
prevProps
===
props
)
{
return
;
}
// Set attributes.
for
(
propName
in
props
)
{
if
(
!
filterNonEntityPropNames
(
propName
)
)
{
continue
;
}
doSetAttribute
(
el
,
props
,
propName
)
;
}
// See if attributes were removed.
if
(
prevProps
)
{
for
(
propName
in
prevProps
)
{
if
(
!
filterNonEntityPropNames
(
propName
)
)
{
continue
;
}
if
(
props
[
propName
]
===
undefined
)
{
el
.
removeAttribute
(
propName
)
;
}
}
}
}

Handle diffing of previous and current attributes.

@param {Element} el
@param {Object|null} prevProps - Previous props map.
@param {Object} props - Current props map.

Handle diffing of previous and current attributes .


function componentDidUpdate(prevProps, prevState) {
      var el = this.el;
      var props = this.props;

      // Update events.
      updateEventListeners(el, prevProps.events, props.events);

      // Update entity.
      if (options.runSetAttributeOnUpdates) {
        updateAttributes(el, prevProps, props);
      }
    }

function
componentDidUpdate
(
prevProps
,
prevState
)
{
var
el
=
this
.
el
;
var
props
=
this
.
props
;
// Update events.
updateEventListeners
(
el
,
prevProps
.
events
,
props
.
events
)
;
// Update entity.
if
(
options
.
runSetAttributeOnUpdates
)
{
updateAttributes
(
el
,
prevProps
,
props
)
;
}
}

Handle updates after the initial render.

Handle updates after the initial render .


function updateEventListeners(el, prevEvents, events) {
  var eventName;

  if (!prevEvents || !events || prevEvents === events) {
    return;
  }

  for (eventName in events) {
    // Didn't change.
    if (prevEvents[eventName] === events[eventName]) {
      continue;
    }

    // If changed, remove old previous event listeners.
    if (prevEvents[eventName]) {
      removeEventListeners(el, eventName, prevEvents[eventName]);
    }

    // Add new event listeners.
    addEventListeners(el, eventName, events[eventName]);
  }

  // See if event handlers were removed.
  for (eventName in prevEvents) {
    if (!events[eventName]) {
      removeEventListeners(el, eventName, prevEvents[eventName]);
    }
  }
}

Handle diffing of previous and current event maps.

@param {Element} el
@param {Object} prevEvents - Previous event map.
@param {Object} events - Current event map.

Handle diffing of previous and current event maps .


function addEventListeners(el, eventName, handlers) {
  var handler;
  var i;

  if (!handlers) {
    return;
  }

  // Convert to array.
  if (handlers.constructor === Function) {
    handlers = [handlers];
  }

  // Register.
  for (i = 0; i < handlers.length; i++) {
    el.addEventListener(eventName, handlers[i]);
  }
}

function
addEventListeners
(
el
,
eventName
,
handlers
)
{
var
handler
;
var
i
;
if
(
!
handlers
)
{
return
;
}
// Convert to array.
if
(
handlers
.
constructor
===
Function
)
{
handlers
=
[
handlers
]
;
}
// Register.
for
(
i
=
0
;
i
<
handlers
.
length
;
i
++
)
{
el
.
addEventListener
(
eventName
,
handlers
[
i
]
)
;
}
}

Register event handlers for an event name to ref.

@param {Element} el - DOM element.
@param {string} eventName
@param {array|function} eventHandlers - Handler function or array of handler functions.

Register event handlers for an event name to ref .


function removeEventListeners(el, eventName, handlers) {
  var handler;
  var i;

  if (!handlers) {
    return;
  }

  // Convert to array.
  if (handlers.constructor === Function) {
    handlers = [handlers];
  }

  // Unregister.
  for (i = 0; i < handlers.length; i++) {
    el.removeEventListener(eventName, handlers[i]);
  }
}

function
removeEventListeners
(
el
,
eventName
,
handlers
)
{
var
handler
;
var
i
;
if
(
!
handlers
)
{
return
;
}
// Convert to array.
if
(
handlers
.
constructor
===
Function
)
{
handlers
=
[
handlers
]
;
}
// Unregister.
for
(
i
=
0
;
i
<
handlers
.
length
;
i
++
)
{
el
.
removeEventListener
(
eventName
,
handlers
[
i
]
)
;
}
}

Unregister event handlers for an event name to ref.

@param {Element} el - DOM element.
@param {string} eventName
@param {array|function} eventHandlers - Handler function or array of handler functions.

Unregister event handlers for an event name to ref .


function makeHooksSafe(routes, store) {
  if (Array.isArray(routes)) {
    return routes.map(route => makeHooksSafe(route, store));
  }

  const onEnter = routes.onEnter;

  if (onEnter) {
    routes.onEnter = function safeOnEnter(...args) {
      try {
        store.getState();
      } catch (err) {
        if (onEnter.length === 3) {
          args[2]();
        }

        // There's no store yet so ignore the hook
        return;
      }

      onEnter.apply(null, args);
    };
  }

  if (routes.childRoutes) {
    makeHooksSafe(routes.childRoutes, store);
  }

  if (routes.indexRoute) {
    makeHooksSafe(routes.indexRoute, store);
  }

  return routes;
}

Wrap the hooks so they don't fire if they're called before the store is initialised. This only happens when doing the first client render of a route that has an onEnter hook

Wrap the hooks so they don t fire if they re called before the store is initialised . This only happens when doing the first client render of a route that has an onEnter hook


function auth (req) {
  if (!req) {
    throw new TypeError('argument req is required')
  }

  if (typeof req !== 'object') {
    throw new TypeError('argument req is required to be an object')
  }

  // get header
  var header = getAuthorization(req)

  // parse header
  return parse(header)
}

Parse the Authorization header field of a request.

@param {object} req
@return {object} with .name and .pass
@public

Parse the Authorization header field of a request .


function getAuthorization (req) {
  if (!req.headers || typeof req.headers !== 'object') {
    throw new TypeError('argument req is required to have headers property')
  }

  return req.headers.authorization
}

Get the Authorization header from request object.
@private

Get the Authorization header from request object .


function parse (string) {
  if (typeof string !== 'string') {
    return undefined
  }

  // parse header
  var match = CREDENTIALS_REGEXP.exec(string)

  if (!match) {
    return undefined
  }

  // decode user pass
  var userPass = USER_PASS_REGEXP.exec(decodeBase64(match[1]))

  if (!userPass) {
    return undefined
  }

  // return credentials object
  return new Credentials(userPass[1], userPass[2])
}

function
parse
(
string
)
{
if
(
typeof
string
!==
'string'
)
{
return
undefined
}
// parse header
var
match
=
CREDENTIALS_REGEXP
.
exec
(
string
)
if
(
!
match
)
{
return
undefined
}
// decode user pass
var
userPass
=
USER_PASS_REGEXP
.
exec
(
decodeBase64
(
match
[
1
]
)
)
if
(
!
userPass
)
{
return
undefined
}
// return credentials object
return
new
Credentials
(
userPass
[
1
]
,
userPass
[
2
]
)
}

Parse basic auth to object.

@param {string} string
@return {object}
@public


function install(cef_version) {

  downloadCef(cef_version,function(err){

    if(err) {
      util.log('Failed to add dependencies','error');
      throw err;
    }

    copyDllWrapper(function(err) {
      if (err) {
        util.log('Failed to copy dll_wrapper.gyp');
        throw err;
      }

      util.log('Done!');
    });
  });
}

function
install
(
cef_version
)
{
downloadCef
(
cef_version
,
function
(
err
)
{
if
(
err
)
{
util
.
log
(
'Failed to add dependencies'
,
'error'
)
;
throw
err
;
}
copyDllWrapper
(
function
(
err
)
{
if
(
err
)
{
util
.
log
(
'Failed to copy dll_wrapper.gyp'
)
;
throw
err
;
}
util
.
log
(
'Done!'
)
;
}
)
;
}
)
;
}


function download(url,onError) {
    var request = require('request');

    util.log('Downloading cef tarball for '+platform+'-'+arch+'...');

    var requestOpts = {
        uri: url,
        onResponse: true
    }

    // basic support for a proxy server
    var proxyUrl = process.env.http_proxy
                || process.env.HTTP_PROXY
                || process.env.npm_config_proxy
    if (proxyUrl) {
      util.log('using proxy: ' + proxyUrl,'verbose');
      requestOpts.proxy = proxyUrl
    }
    return request(requestOpts).on('error',onError).on('response',function(res){onError(null,res)});
}

function
download
(
url
,
onError
)
{
var
request
=
require
(
'request'
)
;
util
.
log
(
'Downloading cef tarball for '
+
platform
+
'-'
+
arch
+
'...'
)
;
var
requestOpts
=
{
uri
:
url
,
onResponse
:
true
}
// basic support for a proxy server
var
proxyUrl
=
process
.
env
.
http_proxy
||
process
.
env
.
HTTP_PROXY
||
process
.
env
.
npm_config_proxy
if
(
proxyUrl
)
{
util
.
log
(
'using proxy: '
+
proxyUrl
,
'verbose'
)
;
requestOpts
.
proxy
=
proxyUrl
}
return
request
(
requestOpts
)
.
on
(
'error'
,
onError
)
.
on
(
'response'
,
function
(
res
)
{
onError
(
,
res
)
}
)
;
}


function checkGlob(filename, globs) {
  // PostCSS turns relative paths into absolute paths
  filename = path.relative(process.cwd(), filename);
  return minimatchList(filename, globs);
}

Check the file matches on of the globs.

@param {string} filename - The filename to test
@param {string[]} globs - An array of glob strings to test the filename against
@return {boolean}

Check the file matches on of the globs .


function getCORSRequest() {
  var xhr = new root.XMLHttpRequest();
  if ('withCredentials' in xhr) {
    xhr.withCredentials = this.withCredentials ? true : false;
    return xhr;
  } else if (!!root.XDomainRequest) {
    return new XDomainRequest();
  } else {
    throw new Error('CORS is not supported by your browser');
  }
}

function
getCORSRequest
(
)
{
var
xhr
=
new
root
.
XMLHttpRequest
(
)
;
if
(
'withCredentials'
in
xhr
)
{
xhr
.
withCredentials
=
this
.
withCredentials
true
:
false
;
return
xhr
;
}
else
if
(
!
!
root
.
XDomainRequest
)
{
return
new
XDomainRequest
(
)
;
}
else
{
throw
new
Error
(
'CORS is not supported by your browser'
)
;
}
}


function getReplyMethod(request) {
  let target = findTargetFromParentInfo(request);

  if (target) {
    return (...a) => {
      if ('isDestroyed' in target && target.isDestroyed()) return;
      target.send(...a);
    };
  } else {
    d("Using reply to main process");
    return (...a) => ipc.send(...a);
  }
}

function
getReplyMethod
(
request
)
{
let
target
=
findTargetFromParentInfo
(
request
)
;
if
(
target
)
{
return
(
...
a
)
=>
{
if
(
'isDestroyed'
in
target
&&
target
.
isDestroyed
(
)
)
return
;
target
.
send
(
...
a
)
;
}
;
}
else
{
d
(
"Using reply to main process"
)
;
return
(
...
a
)
=>
ipc
.
send
(
...
a
)
;
}
}

Determines a way to send a reply back from an incoming eval request.

@param  {Object} request   An object returned from {getSenderIdentifier}

@return {Function}         A function that act like ipc.send, but to a
particular process.

@private

Determines a way to send a reply back from an incoming eval request .


function listenToIpc(channel) {
  return Observable.create((subj) => {
    let listener = (event, ...args) => {
      d(`Got an event for ${channel}: ${JSON.stringify(args)}`);
      subj.next(args);
    };

    d(`Setting up listener! ${channel}`);
    ipc.on(channel, listener);

    return new Subscription(() =>
      ipc.removeListener(channel, listener));
  });
}

function listenToIpc ( channel ) { return Observable . create ( ( subj ) => { let listener = ( event , ... args ) => { d ( ` ${ channel } ${ JSON . stringify ( args ) } ` ) ; subj . next ( args ) ; } ; d ( ` ${ channel } ` ) ; ipc . on ( channel , listener ) ; return new Subscription ( ( ) => ipc . removeListener ( channel , listener ) ) ; } ) ; }

Turns an IPC channel into an Observable

@param  {String} channel     The IPC channel to listen to via `ipc.on`

@return {Observable<Array>}  An Observable which sends IPC args via `onNext`

@private


function getSendMethod(windowOrWebView) {
  if (!windowOrWebView) return (...a) => ipc.send(...a);

  if ('webContents' in windowOrWebView) {
    return (...a) => {
      d(`webContents send: ${JSON.stringify(a)}`);
      if (!windowOrWebView.webContents.isDestroyed()) {
        windowOrWebView.webContents.send(...a);
      } else {
        throw new Error(`WebContents has been destroyed`);
      }
    };
  } else {
    return (...a) => {
      d(`webView send: ${JSON.stringify(a)}`);
      windowOrWebView.send(...a);
    };
  }
}

function getSendMethod ( windowOrWebView ) { if ( ! windowOrWebView ) return ( ... a ) => ipc . send ( ... a ) ; if ( 'webContents' in windowOrWebView ) { return ( ... a ) => { d ( ` ${ JSON . stringify ( a ) } ` ) ; if ( ! windowOrWebView . webContents . isDestroyed ( ) ) { windowOrWebView . webContents . send ( ... a ) ; } else { throw new Error ( ` ` ) ; } } ; } else { return ( ... a ) => { d ( ` ${ JSON . stringify ( a ) } ` ) ; windowOrWebView . send ( ... a ) ; } ; } }

Returns a method that will act like `ipc.send` depending on the parameter
passed to it, so you don't have to check for `webContents`.

@param  {BrowserWindow|WebView} windowOrWebView    The renderer to send to.

@return {Function}                                 A function that behaves like
`ipc.send`.

@private

Returns a method that will act like ipc . send depending on the parameter passed to it so you don t have to check for webContents .


function listenerForId(id, timeout) {
  return listenToIpc(responseChannel)
    .do(([x]) => d(`Got IPC! ${x.id} === ${id}; ${JSON.stringify(x)}`))
    .filter(([receive]) => receive.id === id && id)
    .take(1)
    .mergeMap(([receive]) => {
      if (receive.error) {
        let e = new Error(receive.error.message);
        e.stack = receive.error.stack;
        return Observable.throw(e);
      }

      return Observable.of(receive.result);
    })
    .timeout(timeout);
}

function listenerForId ( id , timeout ) { return listenToIpc ( responseChannel ) . do ( ( [ x ] ) => d ( ` ${ x . id } ${ id } ${ JSON . stringify ( x ) } ` ) ) . filter ( ( [ receive ] ) => receive . id === id && id ) . take ( 1 ) . mergeMap ( ( [ receive ] ) => { if ( receive . error ) { let e = new Error ( receive . error . message ) ; e . stack = receive . error . stack ; return Observable . throw ( e ) ; } return Observable . of ( receive . result ) ; } ) . timeout ( timeout ) ; }

This method creates an Observable Promise that represents a future response
to a remoted call. It filters on ID, then cancels itself once either a
response is returned, or it times out.

@param  {Guid} id                                  The ID of the sent request
@param  {Number} timeout                           The timeout in milliseconds

@return {Observable}                               An Observable Promise
representing the result, or
an OnError with the error.

@private

This method creates an Observable Promise that represents a future response to a remoted call . It filters on ID then cancels itself once either a response is returned or it times out .


function objectAndParentGivenPath(path) {
  let obj = global || window;
  let parent = obj;

  for (let part of path.split('.')) {
    parent = obj;
    obj = obj[part];
  }

  d(`parent: ${parent}, obj: ${obj}`);
  if (typeof(parent) !== 'object') {
    throw new Error(`Couldn't access part of the object window.${path}`);
  }

  return [parent, obj];
}

function objectAndParentGivenPath ( path ) { let obj = global || window ; let parent = obj ; for ( let part of path . split ( '.' ) ) { parent = obj ; obj = obj [ part ] ; } d ( ` ${ parent } ${ obj } ` ) ; if ( typeof ( parent ) !== 'object' ) { throw new Error ( ` ${ path } ` ) ; } return [ parent , obj ] ; }

Walks the global object hierarchy to resolve the actual object that a dotted
object path refers to.

@param  {string} path  A path to the object to execute, in dotted
form i.e. 'document.querySelector'.

@return {Array<string>}      Returns the actual method object and its parent,
usually a Function and its `this` parameter, as
`[parent, obj]`

@private

Walks the global object hierarchy to resolve the actual object that a dotted object path refers to .


function executeMainProcessMethod(moduleName, methodChain, args) {
  const theModule = electron[moduleName];
  const path = methodChain.join('.');
  return get(theModule, path).apply(theModule, args);
}

function executeMainProcessMethod ( moduleName , methodChain , args ) { const theModule = electron [ moduleName ] ; const path = methodChain . join ( '.' ) ; return get ( theModule , path ) . apply ( theModule , args ) ; }

Invokes a method on a module in the main process.

@param {string} moduleName         The name of the module to require
@param {Array<string>} methodChain The path to the module, e.g., ['dock', 'bounce']
@param {Array} args                The arguments to pass to the method

@returns                           The result of calling the method

@private

Invokes a method on a module in the main process .